--- a/.hgtags Mon Jan 04 17:07:23 2016 -0800
+++ b/.hgtags Tue Jan 05 10:38:10 2016 -0800
@@ -341,3 +341,4 @@
139f19d70350238e15e107945cea75082b6380b3 jdk-9+96
4edcff1b9a8875eb6380a2165dfec599e8e3f7c0 jdk-9+97
d00ad2d9049ac60815f70bff445e95df85648bd2 jdk-9+98
+f9bcdce2df26678c3fe468130b535c0342c69b89 jdk-9+99
--- a/.hgtags-top-repo Mon Jan 04 17:07:23 2016 -0800
+++ b/.hgtags-top-repo Tue Jan 05 10:38:10 2016 -0800
@@ -341,3 +341,4 @@
5582a79892596169ebddb3e2c2aa44939e4e3f40 jdk-9+96
75c3897541ecb52ee16d001ea605b12971df7303 jdk-9+97
48987460c7d49a29013963ee44d090194396bb61 jdk-9+98
+7c0577bea4c65d69c5bef67023a89d2efa4fb2f7 jdk-9+99
--- a/common/bin/jib.sh Mon Jan 04 17:07:23 2016 -0800
+++ b/common/bin/jib.sh Tue Jan 05 10:38:10 2016 -0800
@@ -32,7 +32,7 @@
install_data=${mydir}/../../.jib/.data
setup_url() {
- if [ -f "~/.config/jib/jib.conf" ]; then
+ if [ -f ~/.config/jib/jib.conf ]; then
source ~/.config/jib/jib.conf
fi
@@ -50,6 +50,9 @@
if [ -n "${JIB_SERVER}" ]; then
jib_server="${JIB_SERVER}"
fi
+ if [ -n "${JIB_SERVER_MIRRORS}" ]; then
+ jib_server_mirrors="${JIB_SERVER_MIRRORS}"
+ fi
if [ -n "${JIB_REPOSITORY}" ]; then
jib_repository="${JIB_REPOSITORY}"
fi
@@ -70,8 +73,9 @@
jib_url="${JIB_URL}"
data_string="${jib_url}"
else
- data_string="${jib_repository}/${jib_organization}/${jib_module}/${jib_revision}/${jib_module}-${jib_revision}.${jib_ext}"
- jib_url="${jib_server}/${data_string}"
+ jib_path="${jib_repository}/${jib_organization}/${jib_module}/${jib_revision}/${jib_module}-${jib_revision}.${jib_ext}"
+ data_string="${jib_path}"
+ jib_url="${jib_server}/${jib_path}"
fi
}
@@ -104,7 +108,25 @@
${getcmd} ${jib_url} > "${installed_jib_script}.gz"
if [ ! -s "${installed_jib_script}.gz" ]; then
echo "Failed to download ${jib_url}"
- exit 1
+ if [ -n "${jib_path}" -a -n "${jib_server_mirrors}" ]; then
+ OLD_IFS="${IFS}"
+ IFS=" ,"
+ for mirror in ${jib_server_mirrors}; do
+ echo "Trying mirror ${mirror}"
+ jib_url="${mirror}/${jib_path}"
+ ${getcmd} ${jib_url} > "${installed_jib_script}.gz"
+ if [ -s "${installed_jib_script}.gz" ]; then
+ echo "Download from mirror successful"
+ break
+ else
+ echo "Failed to download ${jib_url}"
+ fi
+ done
+ IFS="${OLD_IFS}"
+ fi
+ if [ ! -s "${installed_jib_script}.gz" ]; then
+ exit 1
+ fi
fi
echo "Extracting JIB bootstrap script"
rm -f "${installed_jib_script}"
--- a/corba/.hgtags Mon Jan 04 17:07:23 2016 -0800
+++ b/corba/.hgtags Tue Jan 05 10:38:10 2016 -0800
@@ -341,3 +341,4 @@
feb1bd85d7990dcf5584ca9e53104269c01db006 jdk-9+96
10a482b863582376d4ca229090334b23b05159fc jdk-9+97
ea285530245cf4e0edf0479121a41347d3030eba jdk-9+98
+180212ee1d8710691ba9944593dfc1ff3e4f1532 jdk-9+99
--- a/hotspot/.hgtags Mon Jan 04 17:07:23 2016 -0800
+++ b/hotspot/.hgtags Tue Jan 05 10:38:10 2016 -0800
@@ -501,3 +501,4 @@
a94bb7203596dd632486f1e3655fa5f70541dc08 jdk-9+96
de592ea5f7ba0f8a8c5afc03bd169f7690c72b6f jdk-9+97
e5b1a23be1e105417ba1c4c576ab373eb3fa2c2b jdk-9+98
+f008e8cc10d5b3212fb22d58c96fa01d38654f19 jdk-9+99
--- a/jaxp/.hgtags Mon Jan 04 17:07:23 2016 -0800
+++ b/jaxp/.hgtags Tue Jan 05 10:38:10 2016 -0800
@@ -341,3 +341,4 @@
1f3182529f2c474e5506955ccb3820cfa5822265 jdk-9+96
9c107c050335d7ee63b2a8b38ca5d498f19713a2 jdk-9+97
52b01339235f24c93b679bd6b8fb36a1072ad0ac jdk-9+98
+52774b544850c791f1d1c67db2601b33739b18c9 jdk-9+99
--- a/jaxws/.hgtags Mon Jan 04 17:07:23 2016 -0800
+++ b/jaxws/.hgtags Tue Jan 05 10:38:10 2016 -0800
@@ -344,3 +344,4 @@
b55cebc47555293cf9c2aefb3bf63c56e847ab19 jdk-9+96
7293db4716ee25b814e14f738b9acfb85700e3fa jdk-9+97
67c84077edc3db6b24998b35970b37c01aae985e jdk-9+98
+97b31ca0dd77483cf20ff99a033a455673639578 jdk-9+99
--- a/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/annotation/adapters/XmlAdapter.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/annotation/adapters/XmlAdapter.java Tue Jan 05 10:38:10 2016 -0800
@@ -31,10 +31,10 @@
* <p> <b> Usage: </b> </p>
*
* <p>
- * Some Java types do not map naturally to a XML representation, for
+ * Some Java types do not map naturally to an XML representation, for
* example {@code HashMap} or other non JavaBean classes. Conversely,
- * a XML repsentation may map to a Java type but an application may
- * choose to accesss the XML representation using another Java
+ * an XML representation may map to a Java type but an application may
+ * choose to access the XML representation using another Java
* type. For example, the schema to Java binding rules bind
* xs:DateTime by default to XmlGregorianCalendar. But an application
* may desire to bind xs:DateTime to a custom type,
--- a/jdk/.hgtags Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/.hgtags Tue Jan 05 10:38:10 2016 -0800
@@ -341,3 +341,4 @@
c021b855f51e572e63982654b17742cb1f814fb4 jdk-9+96
fdd84b2265ddce7f50e084b7c8635189bba6f012 jdk-9+97
f86ee68d1107dad41a27efc34306e0e56244a12e jdk-9+98
+e1a789be1535741274c9779f4d4ca3495196b5c3 jdk-9+99
--- a/jdk/make/lib/NioLibraries.gmk Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/make/lib/NioLibraries.gmk Tue Jan 05 10:38:10 2016 -0800
@@ -58,7 +58,10 @@
ifeq ($(OPENJDK_TARGET_OS), aix)
BUILD_LIBNIO_MAPFILE:=$(JDK_TOPDIR)/make/mapfiles/libnio/mapfile-$(OPENJDK_TARGET_OS)
BUILD_LIBNIO_EXFILES += \
- NativeThread.c
+ /NativeThread.c
+ # Notice: we really need the leading slash here because otherwise every
+ # FILE_NAME in EXCLUDE_FILES will actually match any file ending in FILE_NAME
+ # (e.g. 'NativeThread.c' will also exclude 'AixNativeThread.c').
endif
$(eval $(call SetupNativeCompilation,BUILD_LIBNIO, \
--- a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxWatchService.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxWatchService.java Tue Jan 05 10:38:10 2016 -0800
@@ -322,19 +322,6 @@
bytesRead = 0;
}
- // process any pending requests
- if ((nReady > 1) || (nReady == 1 && bytesRead == 0)) {
- try {
- read(socketpair[0], address, BUFFER_SIZE);
- boolean shutdown = processRequests();
- if (shutdown)
- break;
- } catch (UnixException x) {
- if (x.errno() != UnixConstants.EAGAIN)
- throw x;
- }
- }
-
// iterate over buffer to decode events
int offset = 0;
while (offset < bytesRead) {
@@ -369,6 +356,19 @@
offset += (SIZEOF_INOTIFY_EVENT + len);
}
+
+ // process any pending requests
+ if ((nReady > 1) || (nReady == 1 && bytesRead == 0)) {
+ try {
+ read(socketpair[0], address, BUFFER_SIZE);
+ boolean shutdown = processRequests();
+ if (shutdown)
+ break;
+ } catch (UnixException x) {
+ if (x.errno() != UnixConstants.EAGAIN)
+ throw x;
+ }
+ }
}
} catch (UnixException x) {
x.printStackTrace();
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Tue Jan 05 10:38:10 2016 -0800
@@ -45,11 +45,11 @@
import java.util.Set;
import java.util.Stack;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.Vector;
import java.util.Hashtable;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
-import sun.misc.CompoundEnumeration;
import sun.misc.Resource;
import sun.misc.URLClassPath;
import sun.reflect.CallerSensitive;
@@ -2206,3 +2206,36 @@
return sys;
}
}
+
+/*
+ * A utility class that will enumerate over an array of enumerations.
+ */
+final class CompoundEnumeration<E> implements Enumeration<E> {
+ private final Enumeration<E>[] enums;
+ private int index;
+
+ public CompoundEnumeration(Enumeration<E>[] enums) {
+ this.enums = enums;
+ }
+
+ private boolean next() {
+ while (index < enums.length) {
+ if (enums[index] != null && enums[index].hasMoreElements()) {
+ return true;
+ }
+ index++;
+ }
+ return false;
+ }
+
+ public boolean hasMoreElements() {
+ return next();
+ }
+
+ public E nextElement() {
+ if (!next()) {
+ throw new NoSuchElementException();
+ }
+ return enums[index].nextElement();
+ }
+}
--- a/jdk/src/java.base/share/classes/java/net/URLConnection.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/net/URLConnection.java Tue Jan 05 10:38:10 2016 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1550,7 +1550,7 @@
}
if (c1 == 0xFF && c2 == 0xD8 && c3 == 0xFF) {
- if (c4 == 0xE0) {
+ if (c4 == 0xE0 || c4 == 0xEE) {
return "image/jpeg";
}
@@ -1565,10 +1565,6 @@
c11 == 0)) {
return "image/jpeg";
}
-
- if (c4 == 0xEE) {
- return "image/jpg";
- }
}
if (c1 == 0xD0 && c2 == 0xCF && c3 == 0x11 && c4 == 0xE0 &&
--- a/jdk/src/java.base/share/classes/java/time/Duration.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/time/Duration.java Tue Jan 05 10:38:10 2016 -0800
@@ -1385,7 +1385,7 @@
* <p>
* The format of the returned string will be {@code PTnHnMnS}, where n is
* the relevant hours, minutes or seconds part of the duration.
- * Any fractional seconds are placed after a decimal point i the seconds section.
+ * Any fractional seconds are placed after a decimal point in the seconds section.
* If a section has a zero value, it is omitted.
* The hours, minutes and seconds will all have the same sign.
* <p>
@@ -1406,9 +1406,13 @@
if (this == ZERO) {
return "PT0S";
}
- long hours = seconds / SECONDS_PER_HOUR;
- int minutes = (int) ((seconds % SECONDS_PER_HOUR) / SECONDS_PER_MINUTE);
- int secs = (int) (seconds % SECONDS_PER_MINUTE);
+ long effectiveTotalSecs = seconds;
+ if (seconds < 0 && nanos > 0) {
+ effectiveTotalSecs++;
+ }
+ long hours = effectiveTotalSecs / SECONDS_PER_HOUR;
+ int minutes = (int) ((effectiveTotalSecs % SECONDS_PER_HOUR) / SECONDS_PER_MINUTE);
+ int secs = (int) (effectiveTotalSecs % SECONDS_PER_MINUTE);
StringBuilder buf = new StringBuilder(24);
buf.append("PT");
if (hours != 0) {
@@ -1420,18 +1424,18 @@
if (secs == 0 && nanos == 0 && buf.length() > 2) {
return buf.toString();
}
- if (secs < 0 && nanos > 0) {
- if (secs == -1) {
+ if (seconds < 0 && nanos > 0) {
+ if (secs == 0) {
buf.append("-0");
} else {
- buf.append(secs + 1);
+ buf.append(secs);
}
} else {
buf.append(secs);
}
if (nanos > 0) {
int pos = buf.length();
- if (secs < 0) {
+ if (seconds < 0) {
buf.append(2 * NANOS_PER_SECOND - nanos);
} else {
buf.append(nanos + NANOS_PER_SECOND);
--- a/jdk/src/java.base/share/classes/java/time/LocalDate.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/time/LocalDate.java Tue Jan 05 10:38:10 2016 -0800
@@ -147,6 +147,10 @@
* This could be used by an application as a "far future" date.
*/
public static final LocalDate MAX = LocalDate.of(Year.MAX_VALUE, 12, 31);
+ /**
+ * The epoch year {@code LocalDate}, '1970-01-01'.
+ */
+ public static final LocalDate EPOCH = LocalDate.of(1970, 1, 1);
/**
* Serialization version.
@@ -1864,6 +1868,29 @@
return total - DAYS_0000_TO_1970;
}
+ /**
+ * Converts this {@code LocalDate} to the number of seconds since the epoch
+ * of 1970-01-01T00:00:00Z.
+ * <p>
+ * This combines this local date with the specified time and
+ * offset to calculate the epoch-second value, which is the
+ * number of elapsed seconds from 1970-01-01T00:00:00Z.
+ * Instants on the time-line after the epoch are positive, earlier
+ * are negative.
+ *
+ * @param time the local time, not null
+ * @param offset the zone offset, not null
+ * @return the number of seconds since the epoch of 1970-01-01T00:00:00Z, may be negative
+ * @since 9
+ */
+ public long toEpochSecond(LocalTime time, ZoneOffset offset) {
+ Objects.requireNonNull(time, "time");
+ Objects.requireNonNull(offset, "offset");
+ long secs = toEpochDay() * SECONDS_PER_DAY + time.toSecondOfDay();
+ secs -= offset.getTotalSeconds();
+ return secs;
+ }
+
//-----------------------------------------------------------------------
/**
* Compares this date to another date.
--- a/jdk/src/java.base/share/classes/java/time/LocalTime.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/time/LocalTime.java Tue Jan 05 10:38:10 2016 -0800
@@ -1490,6 +1490,30 @@
return total;
}
+ /**
+ * Converts this {@code LocalTime} to the number of seconds since the epoch
+ * of 1970-01-01T00:00:00Z.
+ * <p>
+ * This combines this local time with the specified date and
+ * offset to calculate the epoch-second value, which is the
+ * number of elapsed seconds from 1970-01-01T00:00:00Z.
+ * Instants on the time-line after the epoch are positive, earlier
+ * are negative.
+ *
+ * @param date the local date, not null
+ * @param offset the zone offset, not null
+ * @return the number of seconds since the epoch of 1970-01-01T00:00:00Z, may be negative
+ * @since 9
+ */
+ public long toEpochSecond(LocalDate date, ZoneOffset offset) {
+ Objects.requireNonNull(date, "date");
+ Objects.requireNonNull(offset, "offset");
+ long epochDay = date.toEpochDay();
+ long secs = epochDay * 86400 + toSecondOfDay();
+ secs -= offset.getTotalSeconds();
+ return secs;
+ }
+
//-----------------------------------------------------------------------
/**
* Compares this time to another time.
--- a/jdk/src/java.base/share/classes/java/time/OffsetTime.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/time/OffsetTime.java Tue Jan 05 10:38:10 2016 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1232,6 +1232,28 @@
return nod - offsetNanos;
}
+ /**
+ * Converts this {@code OffsetTime} to the number of seconds since the epoch
+ * of 1970-01-01T00:00:00Z.
+ * <p>
+ * This combines this offset time with the specified date to calculate the
+ * epoch-second value, which is the number of elapsed seconds from
+ * 1970-01-01T00:00:00Z.
+ * Instants on the time-line after the epoch are positive, earlier
+ * are negative.
+ *
+ * @param date the localdate, not null
+ * @return the number of seconds since the epoch of 1970-01-01T00:00:00Z, may be negative
+ * @since 9
+ */
+ public long toEpochSecond(LocalDate date) {
+ Objects.requireNonNull(date, "date");
+ long epochDay = date.toEpochDay();
+ long secs = epochDay * 86400 + time.toSecondOfDay();
+ secs -= offset.getTotalSeconds();
+ return secs;
+ }
+
//-----------------------------------------------------------------------
/**
* Compares this {@code OffsetTime} to another time.
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java Tue Jan 05 10:38:10 2016 -0800
@@ -80,6 +80,7 @@
import java.time.Period;
import java.time.ZoneId;
import java.time.ZoneOffset;
+import java.time.chrono.ChronoLocalDateTime;
import java.time.chrono.Chronology;
import java.time.chrono.IsoChronology;
import java.time.format.DateTimeFormatterBuilder.CompositePrinterParser;
@@ -473,6 +474,17 @@
* day-of-week was valid for the date.
* <li>If an {@linkplain #parsedExcessDays() excess number of days}
* was parsed then it is added to the date if a date is available.
+ * <li> If a second-based field is present, but {@code LocalTime} was not parsed,
+ * then the resolver ensures that milli, micro and nano second values are
+ * available to meet the contract of {@link ChronoField}.
+ * These will be set to zero if missing.
+ * <li>If both date and time were parsed and either an offset or zone is present,
+ * the field {@link ChronoField#INSTANT_SECONDS} is created.
+ * If an offset was parsed then the offset will be combined with the
+ * {@code LocalDateTime} to form the instant, with any zone ignored.
+ * If a {@code ZoneId} was parsed without an offset then the zone will be
+ * combined with the {@code LocalDateTime} to form the instant using the rules
+ * of {@link ChronoLocalDateTime#atZone(ZoneId)}.
* </ol>
*
* @implSpec
--- a/jdk/src/java.base/share/classes/java/time/format/Parsed.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/time/format/Parsed.java Tue Jan 05 10:38:10 2016 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -594,15 +594,16 @@
private void resolveInstant() {
// add instant seconds if we have date, time and zone
+ // Offset (if present) will be given priority over the zone.
if (date != null && time != null) {
- if (zone != null) {
- long instant = date.atTime(time).atZone(zone).getLong(ChronoField.INSTANT_SECONDS);
+ Long offsetSecs = fieldValues.get(OFFSET_SECONDS);
+ if (offsetSecs != null) {
+ ZoneOffset offset = ZoneOffset.ofTotalSeconds(offsetSecs.intValue());
+ long instant = date.atTime(time).atZone(offset).toEpochSecond();
fieldValues.put(INSTANT_SECONDS, instant);
} else {
- Long offsetSecs = fieldValues.get(OFFSET_SECONDS);
- if (offsetSecs != null) {
- ZoneOffset offset = ZoneOffset.ofTotalSeconds(offsetSecs.intValue());
- long instant = date.atTime(time).atZone(offset).getLong(ChronoField.INSTANT_SECONDS);
+ if (zone != null) {
+ long instant = date.atTime(time).atZone(zone).toEpochSecond();
fieldValues.put(INSTANT_SECONDS, instant);
}
}
--- a/jdk/src/java.base/share/classes/java/util/Calendar.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/util/Calendar.java Tue Jan 05 10:38:10 2016 -0800
@@ -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
@@ -2085,8 +2085,10 @@
String calendarType = getCalendarType();
int fieldValue = get(field);
- // the standalone and narrow styles are supported only through CalendarDataProviders.
- if (isStandaloneStyle(style) || isNarrowFormatStyle(style)) {
+ // the standalone/narrow styles and short era are supported only through
+ // CalendarNameProviders.
+ if (isStandaloneStyle(style) || isNarrowFormatStyle(style) ||
+ field == ERA && (style & SHORT) == SHORT) {
String val = CalendarDataUtility.retrieveFieldValueName(calendarType,
field, fieldValue,
style, locale);
--- a/jdk/src/java.base/share/classes/java/util/JapaneseImperialCalendar.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/util/JapaneseImperialCalendar.java Tue Jan 05 10:38:10 2016 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, 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
@@ -1037,14 +1037,16 @@
}
if (size < eras.length) {
int baseStyle = getBaseStyle(style);
- for (int i = size; i < eras.length; i++) {
- Era era = eras[i];
- if (baseStyle == ALL_STYLES || baseStyle == SHORT
- || baseStyle == NARROW_FORMAT) {
- names.put(era.getAbbreviation(), i);
- }
- if (baseStyle == ALL_STYLES || baseStyle == LONG) {
- names.put(era.getName(), i);
+ for (int i = 0; i < eras.length; i++) {
+ if (!names.values().contains(i)) {
+ Era era = eras[i];
+ if (baseStyle == ALL_STYLES || baseStyle == SHORT
+ || baseStyle == NARROW_FORMAT) {
+ names.put(era.getAbbreviation(), i);
+ }
+ if (baseStyle == ALL_STYLES || baseStyle == LONG) {
+ names.put(era.getName(), i);
+ }
}
}
}
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java Tue Jan 05 10:38:10 2016 -0800
@@ -1251,7 +1251,7 @@
idx = getEntryNext(idx);
}
/* If not addSlash, or slash is already there, we are done */
- if (!addSlash || name[name.length - 1] == '/') {
+ if (!addSlash || name.length == 0 || name[name.length - 1] == '/') {
return -1;
}
/* Add slash and try once more */
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/CleanerImpl.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/CleanerImpl.java Tue Jan 05 10:38:10 2016 -0800
@@ -39,7 +39,6 @@
import java.util.function.Function;
import sun.misc.InnocuousThread;
-import sun.misc.ManagedLocalsThread;
/**
* CleanerImpl manages a set of object references and corresponding cleaning actions.
@@ -130,8 +129,8 @@
*/
public void run() {
Thread t = Thread.currentThread();
- ManagedLocalsThread mlThread = (t instanceof ManagedLocalsThread)
- ? (ManagedLocalsThread) t
+ InnocuousThread mlThread = (t instanceof InnocuousThread)
+ ? (InnocuousThread) t
: null;
while (!phantomCleanableList.isListEmpty() ||
!weakCleanableList.isListEmpty() ||
@@ -787,4 +786,3 @@
}
}
-
--- a/jdk/src/java.base/share/classes/sun/misc/CompoundEnumeration.java Mon Jan 04 17:07:23 2016 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc;
-
-import java.util.Enumeration;
-import java.util.NoSuchElementException;
-
-/*
- * A useful utility class that will enumerate over an array of
- * enumerations.
- */
-public class CompoundEnumeration<E> implements Enumeration<E> {
- private Enumeration<E>[] enums;
- private int index = 0;
-
- public CompoundEnumeration(Enumeration<E>[] enums) {
- this.enums = enums;
- }
-
- private boolean next() {
- while (index < enums.length) {
- if (enums[index] != null && enums[index].hasMoreElements()) {
- return true;
- }
- index++;
- }
- return false;
- }
-
- public boolean hasMoreElements() {
- return next();
- }
-
- public E nextElement() {
- if (!next()) {
- throw new NoSuchElementException();
- }
- return enums[index].nextElement();
- }
-}
--- a/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java Tue Jan 05 10:38:10 2016 -0800
@@ -1105,41 +1105,6 @@
return fragLen;
}
-
- /*
- * Is this cipher available?
- *
- * This method can only be called by CipherSuite.BulkCipher.isAvailable()
- * to test the availability of a cipher suites. Please DON'T use it in
- * other places, otherwise, the behavior may be unexpected because we may
- * initialize AEAD cipher improperly in the method.
- */
- Boolean isAvailable() {
- // We won't know whether a cipher for a particular key size is
- // available until the cipher is successfully initialized.
- //
- // We do not initialize AEAD cipher in the constructor. Need to
- // initialize the cipher to ensure that the AEAD mode for a
- // particular key size is supported.
- if (cipherType == AEAD_CIPHER) {
- try {
- Authenticator authenticator =
- new Authenticator(protocolVersion);
- byte[] nonce = authenticator.sequenceNumber();
- byte[] iv = Arrays.copyOf(fixedIv,
- fixedIv.length + nonce.length);
- System.arraycopy(nonce, 0, iv, fixedIv.length, nonce.length);
- GCMParameterSpec spec = new GCMParameterSpec(tagSize * 8, iv);
-
- cipher.init(mode, key, spec, random);
- } catch (Exception e) {
- return Boolean.FALSE;
- }
- } // Otherwise, we have initialized the cipher in the constructor.
-
- return Boolean.TRUE;
- }
-
/**
* Sanity check the length of a fragment before decryption.
*
--- a/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuite.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuite.java Tue Jan 05 10:38:10 2016 -0800
@@ -77,12 +77,6 @@
// minimum priority for default enabled CipherSuites
static final int DEFAULT_SUITES_PRIORITY = 300;
- // Flag indicating if CipherSuite availability can change dynamically.
- // This is the case when we rely on a JCE cipher implementation that
- // may not be available in the installed JCE providers.
- // It is true because we might not have an ECC implementation.
- static final boolean DYNAMIC_AVAILABILITY = true;
-
private static final boolean ALLOW_ECC = Debug.getBooleanProperty
("com.sun.net.ssl.enableECC", true);
@@ -176,9 +170,6 @@
* Return whether this CipherSuite is available for use. A
* CipherSuite may be unavailable even if it is supported
* (i.e. allowed == true) if the required JCE cipher is not installed.
- * In some configuration, this situation may change over time, call
- * CipherSuiteList.clearAvailableCache() before this method to obtain
- * the most current status.
*/
boolean isAvailable() {
return allowed && keyExchange.isAvailable() && cipher.isAvailable();
@@ -471,10 +462,6 @@
B_AES_128_GCM(CIPHER_AES_GCM, AEAD_CIPHER, 16, 12, 4, true),
B_AES_256_GCM(CIPHER_AES_GCM, AEAD_CIPHER, 32, 12, 4, true);
- // Map BulkCipher -> Boolean(available)
- private static final Map<BulkCipher,Boolean> availableCache =
- new HashMap<>(8);
-
// descriptive name including key size, e.g. AES/128
final String description;
@@ -518,6 +505,9 @@
// The secure random used to detect the cipher availability.
private static final SecureRandom secureRandom;
+ // runtime availability
+ private final boolean isAvailable;
+
static {
try {
secureRandom = JsseJce.getSecureRandom();
@@ -542,6 +532,17 @@
this.expandedKeySize = expandedKeySize;
this.exportable = true;
+
+ // availability of this bulk cipher
+ //
+ // Currently all supported ciphers except AES are always available
+ // via the JSSE internal implementations. We also assume AES/128 of
+ // CBC mode is always available since it is shipped with the SunJCE
+ // provider. However, AES/256 is unavailable when the default JCE
+ // policy jurisdiction files are installed because of key length
+ // restrictions.
+ this.isAvailable =
+ allowed ? isUnlimited(keySize, transformation) : false;
}
BulkCipher(String transformation, CipherType cipherType, int keySize,
@@ -558,6 +559,17 @@
this.expandedKeySize = keySize;
this.exportable = false;
+
+ // availability of this bulk cipher
+ //
+ // Currently all supported ciphers except AES are always available
+ // via the JSSE internal implementations. We also assume AES/128 of
+ // CBC mode is always available since it is shipped with the SunJCE
+ // provider. However, AES/256 is unavailable when the default JCE
+ // policy jurisdiction files are installed because of key length
+ // restrictions.
+ this.isAvailable =
+ allowed ? isUnlimited(keySize, transformation) : false;
}
/**
@@ -575,84 +587,27 @@
/**
* Test if this bulk cipher is available. For use by CipherSuite.
- *
- * Currently all supported ciphers except AES are always available
- * via the JSSE internal implementations. We also assume AES/128 of
- * CBC mode is always available since it is shipped with the SunJCE
- * provider. However, AES/256 is unavailable when the default JCE
- * policy jurisdiction files are installed because of key length
- * restrictions, and AEAD is unavailable when the underlying providers
- * do not support AEAD/GCM mode.
*/
boolean isAvailable() {
- if (allowed == false) {
- return false;
- }
-
- if ((this == B_AES_256) ||
- (this.cipherType == CipherType.AEAD_CIPHER)) {
- return isAvailable(this);
- }
-
- // always available
- return true;
- }
-
- // for use by CipherSuiteList.clearAvailableCache();
- static synchronized void clearAvailableCache() {
- if (DYNAMIC_AVAILABILITY) {
- availableCache.clear();
- }
+ return this.isAvailable;
}
- private static synchronized boolean isAvailable(BulkCipher cipher) {
- Boolean b = availableCache.get(cipher);
- if (b == null) {
- int keySizeInBits = cipher.keySize * 8;
- if (keySizeInBits > 128) { // need the JCE unlimited
- // strength jurisdiction policy
- try {
- if (Cipher.getMaxAllowedKeyLength(
- cipher.transformation) < keySizeInBits) {
- b = Boolean.FALSE;
- }
- } catch (Exception e) {
- b = Boolean.FALSE;
- }
- }
+ private static boolean isUnlimited(int keySize, String transformation) {
+ int keySizeInBits = keySize * 8;
+ if (keySizeInBits > 128) { // need the JCE unlimited
+ // strength jurisdiction policy
+ try {
+ if (Cipher.getMaxAllowedKeyLength(
+ transformation) < keySizeInBits) {
- if (b == null) {
- b = Boolean.FALSE; // may be reset to TRUE if
- // the cipher is available
- CipherBox temporary = null;
- try {
- SecretKey key = new SecretKeySpec(
- new byte[cipher.expandedKeySize],
- cipher.algorithm);
- IvParameterSpec iv;
- if (cipher.cipherType == CipherType.AEAD_CIPHER) {
- iv = new IvParameterSpec(
- new byte[cipher.fixedIvSize]);
- } else {
- iv = new IvParameterSpec(new byte[cipher.ivSize]);
- }
- temporary = cipher.newCipher(
- ProtocolVersion.DEFAULT_TLS,
- key, iv, secureRandom, true);
- b = temporary.isAvailable();
- } catch (NoSuchAlgorithmException e) {
- // not available
- } finally {
- if (temporary != null) {
- temporary.dispose();
- }
+ return false;
}
+ } catch (Exception e) {
+ return false;
}
-
- availableCache.put(cipher, b);
}
- return b.booleanValue();
+ return true;
}
@Override
--- a/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuiteList.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuiteList.java Tue Jan 05 10:38:10 2016 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -74,24 +74,12 @@
throw new IllegalArgumentException("CipherSuites may not be null");
}
cipherSuites = new ArrayList<CipherSuite>(names.length);
- // refresh available cache once if a CipherSuite is not available
- // (maybe new JCE providers have been installed)
- boolean refreshed = false;
for (int i = 0; i < names.length; i++) {
String suiteName = names[i];
CipherSuite suite = CipherSuite.valueOf(suiteName);
if (suite.isAvailable() == false) {
- if (refreshed == false) {
- // clear the cache so that the isAvailable() call below
- // does a full check
- clearAvailableCache();
- refreshed = true;
- }
- // still missing?
- if (suite.isAvailable() == false) {
- throw new IllegalArgumentException("Cannot support "
- + suiteName + " with currently installed providers");
- }
+ throw new IllegalArgumentException("Cannot support "
+ + suiteName + " with currently installed providers");
}
cipherSuites.add(suite);
}
@@ -195,16 +183,4 @@
}
s.putBytes16(suiteBytes);
}
-
- /**
- * Clear cache of available ciphersuites. If we support all ciphers
- * internally, there is no need to clear the cache and calling this
- * method has no effect.
- */
- static synchronized void clearAvailableCache() {
- if (CipherSuite.DYNAMIC_AVAILABILITY) {
- CipherSuite.BulkCipher.clearAvailableCache();
- JsseJce.clearEcAvailable();
- }
- }
}
--- a/jdk/src/java.base/share/classes/sun/security/ssl/JsseJce.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/JsseJce.java Tue Jan 05 10:38:10 2016 -0800
@@ -55,11 +55,6 @@
private static final ProviderList fipsProviderList;
- // Flag indicating whether EC crypto is available.
- // If null, then we have not checked yet.
- // If yes, then all the EC based crypto we need is available.
- private static Boolean ecAvailable;
-
// Flag indicating whether Kerberos crypto is available.
// If true, then all the Kerberos-based crypto we need is available.
private static final boolean kerberosAvailable;
@@ -180,24 +175,8 @@
// no instantiation of this class
}
- static synchronized boolean isEcAvailable() {
- if (ecAvailable == null) {
- try {
- JsseJce.getSignature(SIGNATURE_ECDSA);
- JsseJce.getSignature(SIGNATURE_RAWECDSA);
- JsseJce.getKeyAgreement("ECDH");
- JsseJce.getKeyFactory("EC");
- JsseJce.getKeyPairGenerator("EC");
- ecAvailable = true;
- } catch (Exception e) {
- ecAvailable = false;
- }
- }
- return ecAvailable;
- }
-
- static synchronized void clearEcAvailable() {
- ecAvailable = null;
+ static boolean isEcAvailable() {
+ return EcAvailability.isAvailable;
}
static boolean isKerberosAvailable() {
@@ -399,4 +378,27 @@
}
}
+
+ // lazy initialization holder class idiom for static default parameters
+ //
+ // See Effective Java Second Edition: Item 71.
+ private static class EcAvailability {
+ // Is EC crypto available?
+ private final static boolean isAvailable;
+
+ static {
+ boolean mediator = true;
+ try {
+ JsseJce.getSignature(SIGNATURE_ECDSA);
+ JsseJce.getSignature(SIGNATURE_RAWECDSA);
+ JsseJce.getKeyAgreement("ECDH");
+ JsseJce.getKeyFactory("EC");
+ JsseJce.getKeyPairGenerator("EC");
+ } catch (Exception e) {
+ mediator = false;
+ }
+
+ isAvailable = mediator;
+ }
+ }
}
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java Tue Jan 05 10:38:10 2016 -0800
@@ -52,18 +52,8 @@
private X509TrustManager trustManager;
private SecureRandom secureRandom;
- // supported and default protocols
- private ProtocolList defaultServerProtocolList;
- private ProtocolList defaultClientProtocolList;
- private ProtocolList supportedProtocolList;
-
- // supported and default cipher suites
- private CipherSuiteList defaultServerCipherSuiteList;
- private CipherSuiteList defaultClientCipherSuiteList;
- private CipherSuiteList supportedCipherSuiteList;
-
// DTLS cookie exchange manager
- private HelloCookieManager helloCookieManager;
+ private volatile HelloCookieManager helloCookieManager;
private StatusResponseManager statusResponseManager;
@@ -117,6 +107,7 @@
if (debug != null && Debug.isOn("sslctx")) {
System.out.println("done seeding SecureRandom");
}
+
isInitialized = true;
}
@@ -242,13 +233,20 @@
return ephemeralKeyManager;
}
+ // Used for DTLS in server mode only, see ServerHandshaker.
HelloCookieManager getHelloCookieManager() {
if (!isInitialized) {
throw new IllegalStateException("SSLContext is not initialized");
}
- if (helloCookieManager == null) {
- helloCookieManager = getHelloCookieManager(secureRandom);
+ if (helloCookieManager != null) {
+ return helloCookieManager;
+ }
+
+ synchronized (this) {
+ if (helloCookieManager == null) {
+ helloCookieManager = getHelloCookieManager(secureRandom);
+ }
}
return helloCookieManager;
@@ -263,78 +261,34 @@
return statusResponseManager;
}
- abstract SSLParameters getDefaultServerSSLParams();
- abstract SSLParameters getDefaultClientSSLParams();
- abstract SSLParameters getSupportedSSLParams();
+ // Get supported ProtocolList.
+ abstract ProtocolList getSuportedProtocolList();
+
+ // Get default ProtocolList for server mode.
+ abstract ProtocolList getServerDefaultProtocolList();
+
+ // Get default ProtocolList for client mode.
+ abstract ProtocolList getClientDefaultProtocolList();
- // Get supported ProtocolList.
- ProtocolList getSuportedProtocolList() {
- if (supportedProtocolList == null) {
- supportedProtocolList =
- new ProtocolList(getSupportedSSLParams().getProtocols());
- }
+ // Get supported CipherSuiteList.
+ abstract CipherSuiteList getSupportedCipherSuiteList();
- return supportedProtocolList;
- }
+ // Get default CipherSuiteList for server mode.
+ abstract CipherSuiteList getServerDefaultCipherSuiteList();
+
+ // Get default CipherSuiteList for client mode.
+ abstract CipherSuiteList getClientDefaultCipherSuiteList();
// Get default ProtocolList.
ProtocolList getDefaultProtocolList(boolean roleIsServer) {
- if (roleIsServer) {
- if (defaultServerProtocolList == null) {
- defaultServerProtocolList = new ProtocolList(
- getDefaultServerSSLParams().getProtocols());
- }
-
- return defaultServerProtocolList;
- } else {
- if (defaultClientProtocolList == null) {
- defaultClientProtocolList = new ProtocolList(
- getDefaultClientSSLParams().getProtocols());
- }
-
- return defaultClientProtocolList;
- }
- }
-
- // Get supported CipherSuiteList.
- CipherSuiteList getSupportedCipherSuiteList() {
- // The maintenance of cipher suites needs to be synchronized.
- synchronized (this) {
- // Clear cache of available ciphersuites.
- clearAvailableCache();
-
- if (supportedCipherSuiteList == null) {
- supportedCipherSuiteList = getApplicableCipherSuiteList(
- getSuportedProtocolList(), false);
- }
-
- return supportedCipherSuiteList;
- }
+ return roleIsServer ? getServerDefaultProtocolList()
+ : getClientDefaultProtocolList();
}
// Get default CipherSuiteList.
CipherSuiteList getDefaultCipherSuiteList(boolean roleIsServer) {
- // The maintenance of cipher suites needs to be synchronized.
- synchronized (this) {
- // Clear cache of available ciphersuites.
- clearAvailableCache();
-
- if (roleIsServer) {
- if (defaultServerCipherSuiteList == null) {
- defaultServerCipherSuiteList = getApplicableCipherSuiteList(
- getDefaultProtocolList(true), true);
- }
-
- return defaultServerCipherSuiteList;
- } else {
- if (defaultClientCipherSuiteList == null) {
- defaultClientCipherSuiteList = getApplicableCipherSuiteList(
- getDefaultProtocolList(false), true);
- }
-
- return defaultClientCipherSuiteList;
- }
- }
+ return roleIsServer ? getServerDefaultCipherSuiteList()
+ : getClientDefaultCipherSuiteList();
}
/**
@@ -342,8 +296,8 @@
* protocols. See: SSLSocket/SSLEngine.setEnabledProtocols()
*/
boolean isDefaultProtocolList(ProtocolList protocols) {
- return (protocols == defaultServerProtocolList) ||
- (protocols == defaultClientProtocolList);
+ return (protocols == getServerDefaultProtocolList()) ||
+ (protocols == getClientDefaultProtocolList());
}
/**
@@ -351,8 +305,8 @@
* protocols. See: SSLSocket/SSLEngine.setEnabledProtocols()
*/
boolean isDefaultCipherSuiteList(CipherSuiteList cipherSuites) {
- return (cipherSuites == defaultClientCipherSuiteList) ||
- (cipherSuites == defaultServerCipherSuiteList);
+ return (cipherSuites == getServerDefaultCipherSuiteList()) ||
+ (cipherSuites == getClientDefaultCipherSuiteList());
}
/*
@@ -405,24 +359,6 @@
return new CipherSuiteList(suites);
}
- /**
- * Clear cache of available ciphersuites. If we support all ciphers
- * internally, there is no need to clear the cache and calling this
- * method has no effect.
- *
- * Note that every call to clearAvailableCache() and the maintenance of
- * cipher suites need to be synchronized with this instance.
- */
- private void clearAvailableCache() {
- if (CipherSuite.DYNAMIC_AVAILABILITY) {
- supportedCipherSuiteList = null;
- defaultServerCipherSuiteList = null;
- defaultClientCipherSuiteList = null;
- CipherSuite.BulkCipher.clearAvailableCache();
- JsseJce.clearEcAvailable();
- }
- }
-
private static String[] getAvailableProtocols(
ProtocolVersion[] protocolCandidates) {
@@ -479,31 +415,28 @@
* @see SSLContext
*/
private abstract static class AbstractTLSContext extends SSLContextImpl {
- // parameters
- private static final SSLParameters defaultServerSSLParams;
- private static final SSLParameters supportedSSLParams;
+ private static final ProtocolList supportedProtocolList;
+ private static final ProtocolList serverDefaultProtocolList;
+
+ private static final CipherSuiteList supportedCipherSuiteList;
+ private static final CipherSuiteList serverDefaultCipherSuiteList;
static {
- // supported SSL parameters
- supportedSSLParams = new SSLParameters();
-
- // candidates for available protocols
- ProtocolVersion[] candidates;
-
if (SunJSSE.isFIPS()) {
- supportedSSLParams.setProtocols(new String[] {
+ supportedProtocolList = new ProtocolList(new String[] {
ProtocolVersion.TLS10.name,
ProtocolVersion.TLS11.name,
ProtocolVersion.TLS12.name
});
- candidates = new ProtocolVersion[] {
+ serverDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.TLS10,
ProtocolVersion.TLS11,
ProtocolVersion.TLS12
- };
+ }));
} else {
- supportedSSLParams.setProtocols(new String[] {
+ supportedProtocolList = new ProtocolList(new String[] {
ProtocolVersion.SSL20Hello.name,
ProtocolVersion.SSL30.name,
ProtocolVersion.TLS10.name,
@@ -511,28 +444,40 @@
ProtocolVersion.TLS12.name
});
- candidates = new ProtocolVersion[] {
+ serverDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.SSL20Hello,
ProtocolVersion.SSL30,
ProtocolVersion.TLS10,
ProtocolVersion.TLS11,
ProtocolVersion.TLS12
- };
+ }));
}
- defaultServerSSLParams = new SSLParameters();
- defaultServerSSLParams.setProtocols(
- getAvailableProtocols(candidates));
+ supportedCipherSuiteList = getApplicableCipherSuiteList(
+ supportedProtocolList, false); // all supported
+ serverDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ serverDefaultProtocolList, true); // enabled only
}
@Override
- SSLParameters getDefaultServerSSLParams() {
- return defaultServerSSLParams;
+ ProtocolList getSuportedProtocolList() {
+ return supportedProtocolList;
}
@Override
- SSLParameters getSupportedSSLParams() {
- return supportedSSLParams;
+ CipherSuiteList getSupportedCipherSuiteList() {
+ return supportedCipherSuiteList;
+ }
+
+ @Override
+ ProtocolList getServerDefaultProtocolList() {
+ return serverDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getServerDefaultCipherSuiteList() {
+ return serverDefaultCipherSuiteList;
}
@Override
@@ -552,30 +497,35 @@
* @see SSLContext
*/
public static final class TLS10Context extends AbstractTLSContext {
- private static final SSLParameters defaultClientSSLParams;
+ private static final ProtocolList clientDefaultProtocolList;
+ private static final CipherSuiteList clientDefaultCipherSuiteList;
static {
- // candidates for available protocols
- ProtocolVersion[] candidates;
if (SunJSSE.isFIPS()) {
- candidates = new ProtocolVersion[] {
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.TLS10
- };
+ }));
} else {
- candidates = new ProtocolVersion[] {
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.SSL30,
ProtocolVersion.TLS10
- };
+ }));
}
- defaultClientSSLParams = new SSLParameters();
- defaultClientSSLParams.setProtocols(
- getAvailableProtocols(candidates));
+ clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ clientDefaultProtocolList, true); // enabled only
}
@Override
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getClientDefaultCipherSuiteList() {
+ return clientDefaultCipherSuiteList;
}
}
@@ -585,32 +535,37 @@
* @see SSLContext
*/
public static final class TLS11Context extends AbstractTLSContext {
- private static final SSLParameters defaultClientSSLParams;
+ private static final ProtocolList clientDefaultProtocolList;
+ private static final CipherSuiteList clientDefaultCipherSuiteList;
static {
- // candidates for available protocols
- ProtocolVersion[] candidates;
if (SunJSSE.isFIPS()) {
- candidates = new ProtocolVersion[] {
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.TLS10,
ProtocolVersion.TLS11
- };
+ }));
} else {
- candidates = new ProtocolVersion[] {
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.SSL30,
ProtocolVersion.TLS10,
ProtocolVersion.TLS11
- };
+ }));
}
- defaultClientSSLParams = new SSLParameters();
- defaultClientSSLParams.setProtocols(
- getAvailableProtocols(candidates));
+ clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ clientDefaultProtocolList, true); // enabled only
}
@Override
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getClientDefaultCipherSuiteList() {
+ return clientDefaultCipherSuiteList;
}
}
@@ -620,34 +575,39 @@
* @see SSLContext
*/
public static final class TLS12Context extends AbstractTLSContext {
- private static final SSLParameters defaultClientSSLParams;
+ private static final ProtocolList clientDefaultProtocolList;
+ private static final CipherSuiteList clientDefaultCipherSuiteList;
static {
- // candidates for available protocols
- ProtocolVersion[] candidates;
if (SunJSSE.isFIPS()) {
- candidates = new ProtocolVersion[] {
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.TLS10,
ProtocolVersion.TLS11,
ProtocolVersion.TLS12
- };
+ }));
} else {
- candidates = new ProtocolVersion[] {
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.SSL30,
ProtocolVersion.TLS10,
ProtocolVersion.TLS11,
ProtocolVersion.TLS12
- };
+ }));
}
- defaultClientSSLParams = new SSLParameters();
- defaultClientSSLParams.setProtocols(
- getAvailableProtocols(candidates));
+ clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ clientDefaultProtocolList, true); // enabled only
}
@Override
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getClientDefaultCipherSuiteList() {
+ return clientDefaultCipherSuiteList;
}
}
@@ -719,7 +679,9 @@
*/
private static class CustomizedTLSContext extends AbstractTLSContext {
- private static final SSLParameters defaultClientSSLParams;
+ private static final ProtocolList clientDefaultProtocolList;
+ private static final CipherSuiteList clientDefaultCipherSuiteList;
+
private static IllegalArgumentException reservedException = null;
// Don't want a java.lang.LinkageError for illegal system property.
@@ -766,11 +728,13 @@
candidates = customizedTLSProtocols.toArray(candidates);
}
- defaultClientSSLParams = new SSLParameters();
- defaultClientSSLParams.setProtocols(
+ clientDefaultProtocolList = new ProtocolList(
getAvailableProtocols(candidates));
+ clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ clientDefaultProtocolList, true); // enabled only
} else {
- defaultClientSSLParams = null; // unlikely to be used
+ clientDefaultProtocolList = null; // unlikely to be used
+ clientDefaultCipherSuiteList = null; // unlikely to be used
}
}
@@ -781,8 +745,13 @@
}
@Override
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getClientDefaultCipherSuiteList() {
+ return clientDefaultCipherSuiteList;
}
}
@@ -795,71 +764,53 @@
// use the default constructor and methods
}
- /*
- * The SSLContext implementation for default "Default" algorithm
- *
- * @see SSLContext
- */
- public static final class DefaultSSLContext extends CustomizedTLSContext {
+ // lazy initialization holder class idiom for static default parameters
+ //
+ // See Effective Java Second Edition: Item 71.
+ private static final class DefaultManagersHolder {
private static final String NONE = "NONE";
private static final String P11KEYSTORE = "PKCS11";
- private static volatile SSLContextImpl defaultImpl;
+ private static final TrustManager[] trustManagers;
+ private static final KeyManager[] keyManagers;
- private static TrustManager[] defaultTrustManagers;
- private static KeyManager[] defaultKeyManagers;
+ static Exception reservedException = null;
- public DefaultSSLContext() throws Exception {
+ static {
+ TrustManager[] tmMediator;
try {
- super.engineInit(getDefaultKeyManager(),
- getDefaultTrustManager(), null);
+ tmMediator = getTrustManagers();
} catch (Exception e) {
- if (debug != null && Debug.isOn("defaultctx")) {
- System.out.println("default context init failed: " + e);
+ reservedException = e;
+ tmMediator = new TrustManager[0];
+ }
+ trustManagers = tmMediator;
+
+ if (reservedException == null) {
+ KeyManager[] kmMediator;
+ try {
+ kmMediator = getKeyManagers();
+ } catch (Exception e) {
+ reservedException = e;
+ kmMediator = new KeyManager[0];
}
- throw e;
- }
-
- if (defaultImpl == null) {
- defaultImpl = this;
+ keyManagers = kmMediator;
+ } else {
+ keyManagers = new KeyManager[0];
}
}
- @Override
- protected void engineInit(KeyManager[] km, TrustManager[] tm,
- SecureRandom sr) throws KeyManagementException {
- throw new KeyManagementException
- ("Default SSLContext is initialized automatically");
- }
-
- static synchronized SSLContextImpl getDefaultImpl() throws Exception {
- if (defaultImpl == null) {
- new DefaultSSLContext();
- }
- return defaultImpl;
- }
-
- private static synchronized TrustManager[] getDefaultTrustManager()
- throws Exception {
- if (defaultTrustManagers != null) {
- return defaultTrustManagers;
- }
-
+ private static TrustManager[] getTrustManagers() throws Exception {
KeyStore ks =
TrustManagerFactoryImpl.getCacertsKeyStore("defaultctx");
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
- defaultTrustManagers = tmf.getTrustManagers();
- return defaultTrustManagers;
+ return tmf.getTrustManagers();
}
- private static synchronized KeyManager[] getDefaultKeyManager()
- throws Exception {
- if (defaultKeyManagers != null) {
- return defaultKeyManagers;
- }
+ private static KeyManager[] getKeyManagers() throws Exception {
final Map<String,String> props = new HashMap<>();
AccessController.doPrivileged(
@@ -956,8 +907,71 @@
kmf.init(ks, passwd);
}
- defaultKeyManagers = kmf.getKeyManagers();
- return defaultKeyManagers;
+ return kmf.getKeyManagers();
+ }
+ }
+
+ // lazy initialization holder class idiom for static default parameters
+ //
+ // See Effective Java Second Edition: Item 71.
+ private static final class DefaultSSLContextHolder {
+
+ private static final SSLContextImpl sslContext;
+ static Exception reservedException = null;
+
+ static {
+ SSLContextImpl mediator = null;
+ if (DefaultManagersHolder.reservedException != null) {
+ reservedException = DefaultManagersHolder.reservedException;
+ } else {
+ try {
+ mediator = new DefaultSSLContext();
+ } catch (Exception e) {
+ reservedException = e;
+ }
+ }
+
+ sslContext = mediator;
+ }
+ }
+
+ /*
+ * The SSLContext implementation for default "Default" algorithm
+ *
+ * @see SSLContext
+ */
+ public static final class DefaultSSLContext extends CustomizedTLSContext {
+
+ // public constructor for SSLContext.getInstance("Default")
+ public DefaultSSLContext() throws Exception {
+ if (DefaultManagersHolder.reservedException != null) {
+ throw DefaultManagersHolder.reservedException;
+ }
+
+ try {
+ super.engineInit(DefaultManagersHolder.keyManagers,
+ DefaultManagersHolder.trustManagers, null);
+ } catch (Exception e) {
+ if (debug != null && Debug.isOn("defaultctx")) {
+ System.out.println("default context init failed: " + e);
+ }
+ throw e;
+ }
+ }
+
+ @Override
+ protected void engineInit(KeyManager[] km, TrustManager[] tm,
+ SecureRandom sr) throws KeyManagementException {
+ throw new KeyManagementException
+ ("Default SSLContext is initialized automatically");
+ }
+
+ static SSLContextImpl getDefaultImpl() throws Exception {
+ if (DefaultSSLContextHolder.reservedException != null) {
+ throw DefaultSSLContextHolder.reservedException;
+ }
+
+ return DefaultSSLContextHolder.sslContext;
}
}
@@ -971,39 +985,50 @@
* @see SSLContext
*/
private abstract static class AbstractDTLSContext extends SSLContextImpl {
- // parameters
- private static final SSLParameters defaultServerSSLParams;
- private static final SSLParameters supportedSSLParams;
+ private static final ProtocolList supportedProtocolList;
+ private static final ProtocolList serverDefaultProtocolList;
+
+ private static final CipherSuiteList supportedCipherSuiteList;
+ private static final CipherSuiteList serverDefaultCipherSuiteList;
static {
- // supported SSL parameters
- supportedSSLParams = new SSLParameters();
-
// Both DTLSv1.0 and DTLSv1.2 can be used in FIPS mode.
- supportedSSLParams.setProtocols(new String[] {
+ supportedProtocolList = new ProtocolList(new String[] {
ProtocolVersion.DTLS10.name,
ProtocolVersion.DTLS12.name
});
- // candidates for available protocols
- ProtocolVersion[] candidates = new ProtocolVersion[] {
+ // available protocols for server mode
+ serverDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.DTLS10,
ProtocolVersion.DTLS12
- };
+ }));
- defaultServerSSLParams = new SSLParameters();
- defaultServerSSLParams.setProtocols(
- getAvailableProtocols(candidates));
+ supportedCipherSuiteList = getApplicableCipherSuiteList(
+ supportedProtocolList, false); // all supported
+ serverDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ serverDefaultProtocolList, true); // enabled only
}
@Override
- SSLParameters getDefaultServerSSLParams() {
- return defaultServerSSLParams;
+ ProtocolList getSuportedProtocolList() {
+ return supportedProtocolList;
}
@Override
- SSLParameters getSupportedSSLParams() {
- return supportedSSLParams;
+ CipherSuiteList getSupportedCipherSuiteList() {
+ return supportedCipherSuiteList;
+ }
+
+ @Override
+ ProtocolList getServerDefaultProtocolList() {
+ return serverDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getServerDefaultCipherSuiteList() {
+ return serverDefaultCipherSuiteList;
}
@Override
@@ -1028,22 +1053,28 @@
* @see SSLContext
*/
public static final class DTLS10Context extends AbstractDTLSContext {
- private static final SSLParameters defaultClientSSLParams;
+ private static final ProtocolList clientDefaultProtocolList;
+ private static final CipherSuiteList clientDefaultCipherSuiteList;
static {
- // candidates for available protocols
- ProtocolVersion[] candidates = new ProtocolVersion[] {
+ // available protocols for client mode
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.DTLS10
- };
+ }));
- defaultClientSSLParams = new SSLParameters();
- defaultClientSSLParams.setProtocols(
- getAvailableProtocols(candidates));
+ clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ clientDefaultProtocolList, true); // enabled only
}
@Override
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getClientDefaultCipherSuiteList() {
+ return clientDefaultCipherSuiteList;
}
}
@@ -1053,23 +1084,29 @@
* @see SSLContext
*/
public static final class DTLS12Context extends AbstractDTLSContext {
- private static final SSLParameters defaultClientSSLParams;
+ private static final ProtocolList clientDefaultProtocolList;
+ private static final CipherSuiteList clientDefaultCipherSuiteList;
static {
- // candidates for available protocols
- ProtocolVersion[] candidates = new ProtocolVersion[] {
+ // available protocols for client mode
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.DTLS10,
ProtocolVersion.DTLS12
- };
+ }));
- defaultClientSSLParams = new SSLParameters();
- defaultClientSSLParams.setProtocols(
- getAvailableProtocols(candidates));
+ clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ clientDefaultProtocolList, true); // enabled only
}
@Override
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getClientDefaultCipherSuiteList() {
+ return clientDefaultCipherSuiteList;
}
}
@@ -1079,7 +1116,9 @@
* @see SSLContext
*/
private static class CustomizedDTLSContext extends AbstractDTLSContext {
- private static final SSLParameters defaultClientSSLParams;
+ private static final ProtocolList clientDefaultProtocolList;
+ private static final CipherSuiteList clientDefaultCipherSuiteList;
+
private static IllegalArgumentException reservedException = null;
// Don't want a java.lang.LinkageError for illegal system property.
@@ -1119,11 +1158,13 @@
candidates = customizedDTLSProtocols.toArray(candidates);
}
- defaultClientSSLParams = new SSLParameters();
- defaultClientSSLParams.setProtocols(
+ clientDefaultProtocolList = new ProtocolList(
getAvailableProtocols(candidates));
+ clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ clientDefaultProtocolList, true); // enabled only
} else {
- defaultClientSSLParams = null; // unlikely to be used
+ clientDefaultProtocolList = null; // unlikely to be used
+ clientDefaultCipherSuiteList = null; // unlikely to be used
}
}
@@ -1134,8 +1175,13 @@
}
@Override
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getClientDefaultCipherSuiteList() {
+ return clientDefaultCipherSuiteList;
}
}
--- a/jdk/src/java.base/windows/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/java.base/windows/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java Tue Jan 05 10:38:10 2016 -0800
@@ -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
@@ -38,8 +38,10 @@
import java.util.Calendar;
import java.util.Collections;
import java.util.Currency;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
+import java.util.Map;
import java.util.ResourceBundle.Control;
import java.util.Set;
import java.util.TimeZone;
@@ -47,6 +49,7 @@
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.spi.CalendarDataProvider;
+import java.util.spi.CalendarNameProvider;
import java.util.spi.CurrencyNameProvider;
import java.util.spi.LocaleNameProvider;
import sun.util.spi.CalendarProvider;
@@ -81,6 +84,9 @@
private static final int DN_LOCALE_REGION = 4;
private static final int DN_LOCALE_VARIANT = 5;
+ // Windows Calendar IDs
+ private static final int CAL_JAPAN = 3;
+
// Native Calendar ID to LDML calendar type map
private static final String[] calIDToLDML = {
"",
@@ -95,7 +101,8 @@
"gregory_fr",
"gregory_ar",
"gregory_en",
- "gregory_fr",
+ "gregory_fr", "", "", "", "", "", "", "", "", "", "",
+ "islamic-umalqura",
};
// Caches
@@ -362,6 +369,50 @@
};
}
+ public static CalendarNameProvider getCalendarNameProvider() {
+ return new CalendarNameProvider() {
+ @Override
+ public Locale[] getAvailableLocales() {
+ return getSupportedCalendarLocales();
+ }
+
+ @Override
+ public boolean isSupportedLocale(Locale locale) {
+ return isSupportedCalendarLocale(locale);
+ }
+
+ @Override
+ public String getDisplayName(String calendarType, int field,
+ int value, int style, Locale locale) {
+ String[] names = getCalendarDisplayStrings(removeExtensions(locale).toLanguageTag(),
+ getCalendarIDFromLDMLType(calendarType), field, style);
+ if (names != null && value >= 0 && value < names.length) {
+ return names[value];
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public Map<String, Integer> getDisplayNames(String calendarType,
+ int field, int style, Locale locale) {
+ Map<String, Integer> map = null;
+ String[] names = getCalendarDisplayStrings(removeExtensions(locale).toLanguageTag(),
+ getCalendarIDFromLDMLType(calendarType), field, style);
+ if (names != null) {
+ map = new HashMap<>();
+ for (int value = 0; value < names.length; value++) {
+ if (names[value] != null) {
+ map.put(names[value], value);
+ }
+ }
+ map = map.isEmpty() ? null : map;
+ }
+ return map;
+ }
+ };
+ }
+
public static CalendarProvider getCalendarProvider() {
return new CalendarProvider() {
@Override
@@ -496,15 +547,7 @@
}
private static boolean isSupportedCalendarLocale(Locale locale) {
- Locale base = locale;
-
- if (base.hasExtensions() || base.getVariant() != "") {
- // strip off extensions and variant.
- base = new Locale.Builder()
- .setLocale(locale)
- .clearExtensions()
- .build();
- }
+ Locale base = stripVariantAndExtensions(locale);
if (!supportedLocaleSet.contains(base)) {
return false;
@@ -569,11 +612,23 @@
}
private static boolean isJapaneseCalendar() {
- return getCalendarID("ja-JP") == 3; // 3: CAL_JAPAN
+ return getCalendarID("ja-JP") == CAL_JAPAN;
+ }
+
+ private static Locale stripVariantAndExtensions(Locale locale) {
+ if (locale.hasExtensions() || locale.getVariant() != "") {
+ // strip off extensions and variant.
+ locale = new Locale.Builder()
+ .setLocale(locale)
+ .clearExtensions()
+ .build();
+ }
+
+ return locale;
}
private static Locale getCalendarLocale(Locale locale) {
- int calid = getCalendarID(locale.toLanguageTag());
+ int calid = getCalendarID(stripVariantAndExtensions(locale).toLanguageTag());
if (calid > 0 && calid < calIDToLDML.length) {
Locale.Builder lb = new Locale.Builder();
String[] caltype = calIDToLDML[calid].split("_");
@@ -589,6 +644,15 @@
return locale;
}
+ private static int getCalendarIDFromLDMLType(String ldmlType) {
+ for (int i = 0; i < calIDToLDML.length; i++) {
+ if (calIDToLDML[i].startsWith(ldmlType)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
private static Locale getNumberLocale(Locale src) {
if (JRELocaleConstants.TH_TH.equals(src)) {
if (isNativeDigit("th-TH")) {
@@ -639,6 +703,9 @@
// For CalendarDataProvider
private static native int getCalendarDataValue(String langTag, int type);
+ // For CalendarNameProvider
+ private static native String[] getCalendarDisplayStrings(String langTag, int calid, int field, int style);
+
// For Locale/CurrencyNameProvider
private static native String getDisplayString(String langTag, int key, String value);
}
--- a/jdk/src/java.base/windows/native/libjava/HostLocaleProviderAdapter_md.c Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/java.base/windows/native/libjava/HostLocaleProviderAdapter_md.c Tue Jan 05 10:38:10 2016 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,22 +31,33 @@
#define BUFLEN 256
+// java.util.Calendar constants
+#define CALENDAR_FIELD_ERA 0 // Calendar.ERA
+#define CALENDAR_FIELD_MONTH 2 // Calendar.MONTH
+#define CALENDAR_STYLE_SHORT_MASK 0x00000001 // Calendar.SHORT
+#define CALENDAR_STYLE_STANDALONE_MASK 0x00008000 // Calendar.STANDALONE
+
// global variables
typedef int (WINAPI *PGLIE)(const jchar *, LCTYPE, LPWSTR, int);
typedef int (WINAPI *PGCIE)(const jchar *, CALID, LPCWSTR, CALTYPE, LPWSTR, int, LPDWORD);
+typedef int (WINAPI *PECIEE)(CALINFO_ENUMPROCEXEX, const jchar *, CALID, LPCWSTR, CALTYPE, LPARAM);
PGLIE pGetLocaleInfoEx;
PGCIE pGetCalendarInfoEx;
+PECIEE pEnumCalendarInfoExEx;
BOOL initialized = FALSE;
// prototypes
int getLocaleInfoWrapper(const jchar *langtag, LCTYPE type, LPWSTR data, int buflen);
int getCalendarInfoWrapper(const jchar *langtag, CALID id, LPCWSTR reserved, CALTYPE type, LPWSTR data, int buflen, LPDWORD val);
jint getCalendarID(const jchar *langtag);
-void replaceCalendarArrayElems(JNIEnv *env, jstring jlangtag, jobjectArray jarray,
- CALTYPE* pCalTypes, int offset, int length);
+void replaceCalendarArrayElems(JNIEnv *env, jstring jlangtag, jint calid, jobjectArray jarray,
+ CALTYPE* pCalTypes, int offset, int length, int style);
WCHAR * getNumberPattern(const jchar * langtag, const jint numberStyle);
void getNumberPart(const jchar * langtag, const jint numberStyle, WCHAR * number);
void getFixPart(const jchar * langtag, const jint numberStyle, BOOL positive, BOOL prefix, WCHAR * ret);
+int enumCalendarInfoWrapper(const jchar * langtag, CALID calid, CALTYPE type, LPWSTR buf, int buflen);
+BOOL CALLBACK EnumCalendarInfoProc(LPWSTR lpCalInfoStr, CALID calid, LPWSTR lpReserved, LPARAM lParam);
+jobjectArray getErasImpl(JNIEnv *env, jstring jlangtag, jint calid, jint style, jobjectArray eras);
// from java_props_md.c
extern __declspec(dllexport) const char * getJavaIDFromLangID(LANGID langID);
@@ -83,6 +94,8 @@
CAL_SABBREVMONTHNAME13,
};
+#define MONTHTYPES (sizeof(monthsType) / sizeof(CALTYPE))
+
CALTYPE wDaysType[] = {
CAL_SDAYNAME7,
CAL_SDAYNAME1,
@@ -155,6 +168,11 @@
}
};
+
+// Localized region name for unknown regions (Windows 10)
+#define UNKNOWN_REGION L"Unknown Region ("
+#define UNKNOWN_REGION_SIZE wcslen(UNKNOWN_REGION)
+
/*
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
* Method: initialize
@@ -169,11 +187,15 @@
pGetCalendarInfoEx = (PGCIE)GetProcAddress(
GetModuleHandle("kernel32.dll"),
"GetCalendarInfoEx");
+ pEnumCalendarInfoExEx = (PECIEE)GetProcAddress(
+ GetModuleHandle("kernel32.dll"),
+ "EnumCalendarInfoExEx");
initialized =TRUE;
}
return pGetLocaleInfoEx != NULL &&
- pGetCalendarInfoEx != NULL;
+ pGetCalendarInfoEx != NULL &&
+ pEnumCalendarInfoExEx != NULL;
}
/*
@@ -300,23 +322,7 @@
*/
JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getEras
(JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray eras) {
- WCHAR ad[BUFLEN];
- const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
- jstring tmp_string;
- CHECK_NULL_RETURN(langtag, eras);
-
- getCalendarInfoWrapper(langtag, getCalendarID(langtag), NULL,
- CAL_SERASTRING, ad, BUFLEN, NULL);
-
- // Windows does not provide B.C. era.
- tmp_string = (*env)->NewString(env, ad, (jsize)wcslen(ad));
- if (tmp_string != NULL) {
- (*env)->SetObjectArrayElement(env, eras, 1, tmp_string);
- }
-
- (*env)->ReleaseStringChars(env, jlangtag, langtag);
-
- return eras;
+ return getErasImpl(env, jlangtag, -1, 0, eras);
}
/*
@@ -326,8 +332,8 @@
*/
JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getMonths
(JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray months) {
- replaceCalendarArrayElems(env, jlangtag, months, monthsType,
- 0, sizeof(monthsType)/sizeof(CALTYPE));
+ replaceCalendarArrayElems(env, jlangtag, -1, months, monthsType,
+ 0, MONTHTYPES, 0);
return months;
}
@@ -338,8 +344,8 @@
*/
JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getShortMonths
(JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray smonths) {
- replaceCalendarArrayElems(env, jlangtag, smonths, sMonthsType,
- 0, sizeof(sMonthsType)/sizeof(CALTYPE));
+ replaceCalendarArrayElems(env, jlangtag, -1, smonths, sMonthsType,
+ 0, MONTHTYPES, 0);
return smonths;
}
@@ -350,8 +356,8 @@
*/
JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getWeekdays
(JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray wdays) {
- replaceCalendarArrayElems(env, jlangtag, wdays, wDaysType,
- 1, sizeof(wDaysType)/sizeof(CALTYPE));
+ replaceCalendarArrayElems(env, jlangtag, -1, wdays, wDaysType,
+ 1, sizeof(wDaysType)/sizeof(CALTYPE), 0);
return wdays;
}
@@ -362,8 +368,8 @@
*/
JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getShortWeekdays
(JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray swdays) {
- replaceCalendarArrayElems(env, jlangtag, swdays, sWDaysType,
- 1, sizeof(sWDaysType)/sizeof(CALTYPE));
+ replaceCalendarArrayElems(env, jlangtag, -1, swdays, sWDaysType,
+ 1, sizeof(sWDaysType)/sizeof(CALTYPE), 0);
return swdays;
}
@@ -676,6 +682,41 @@
/*
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
+ * Method: getCalendarDisplayStrings
+ * Signature: (Ljava/lang/String;III)[Ljava/lang/String;
+ */
+JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCalendarDisplayStrings
+ (JNIEnv *env, jclass cls, jstring jlangtag, jint calid, jint field, jint style) {
+ jobjectArray ret = NULL;
+ CALTYPE * pCalType = NULL;
+
+ switch (field) {
+ case CALENDAR_FIELD_ERA:
+ return getErasImpl(env, jlangtag, calid, style, NULL);
+
+ case CALENDAR_FIELD_MONTH:
+ ret = (*env)->NewObjectArray(env, MONTHTYPES,
+ (*env)->FindClass(env, "java/lang/String"), NULL);
+ if (ret != NULL) {
+ if (style & CALENDAR_STYLE_SHORT_MASK) {
+ pCalType = sMonthsType;
+ } else {
+ pCalType = monthsType;
+ }
+
+ replaceCalendarArrayElems(env, jlangtag, calid, ret, pCalType,
+ 0, MONTHTYPES, style);
+ }
+ return ret;
+
+ default:
+ // not supported
+ return NULL;
+ }
+}
+
+/*
+ * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
* Method: getDisplayString
* Signature: (Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String;
*/
@@ -714,10 +755,15 @@
(*env)->ReleaseStringChars(env, jStr, pjChar);
if (got) {
- return (*env)->NewString(env, buf, (jsize)wcslen(buf));
- } else {
- return NULL;
+ // Hack: Windows 10 returns "Unknown Region (XX)" for localized XX region name.
+ // Take that as not known.
+ if (type != sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_LOCALE_REGION ||
+ wcsncmp(UNKNOWN_REGION, buf, UNKNOWN_REGION_SIZE) != 0) {
+ return (*env)->NewString(env, buf, (jsize)wcslen(buf));
+ }
}
+
+ return NULL;
}
int getLocaleInfoWrapper(const jchar *langtag, LCTYPE type, LPWSTR data, int buflen) {
@@ -753,35 +799,62 @@
}
jint getCalendarID(const jchar *langtag) {
- DWORD type;
+ DWORD type = -1;
int got = getLocaleInfoWrapper(langtag,
LOCALE_ICALENDARTYPE | LOCALE_RETURN_NUMBER,
(LPWSTR)&type, sizeof(type));
if (got) {
- return type;
- } else {
- return 0;
+ switch (type) {
+ case CAL_GREGORIAN:
+ case CAL_GREGORIAN_US:
+ case CAL_JAPAN:
+ case CAL_TAIWAN:
+ case CAL_HIJRI:
+ case CAL_THAI:
+ case CAL_GREGORIAN_ME_FRENCH:
+ case CAL_GREGORIAN_ARABIC:
+ case CAL_GREGORIAN_XLIT_ENGLISH:
+ case CAL_GREGORIAN_XLIT_FRENCH:
+ case CAL_UMALQURA:
+ break;
+
+ default:
+ // non-supported calendars return -1
+ type = -1;
+ break;
+ }
}
+
+ return type;
}
-void replaceCalendarArrayElems(JNIEnv *env, jstring jlangtag, jobjectArray jarray, CALTYPE* pCalTypes, int offset, int length) {
+void replaceCalendarArrayElems(JNIEnv *env, jstring jlangtag, jint calid, jobjectArray jarray, CALTYPE* pCalTypes, int offset, int length, int style) {
WCHAR name[BUFLEN];
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
- int calid;
jstring tmp_string;
+ CALTYPE isGenitive;
CHECK_NULL(langtag);
- calid = getCalendarID(langtag);
+
+ if (calid < 0) {
+ calid = getCalendarID(langtag);
+ }
if (calid != -1) {
int i;
+
+ if (!(style & CALENDAR_STYLE_STANDALONE_MASK)) {
+ isGenitive = CAL_RETURN_GENITIVE_NAMES;
+ }
+
for (i = 0; i < length; i++) {
- getCalendarInfoWrapper(langtag, calid, NULL,
- pCalTypes[i], name, BUFLEN, NULL);
- tmp_string = (*env)->NewString(env, name, (jsize)wcslen(name));
- if (tmp_string != NULL) {
- (*env)->SetObjectArrayElement(env, jarray, i + offset, tmp_string);
+ if (getCalendarInfoWrapper(langtag, calid, NULL,
+ pCalTypes[i] | isGenitive, name, BUFLEN, NULL) != 0) {
+ tmp_string = (*env)->NewString(env, name, (jsize)wcslen(name));
+ if (tmp_string != NULL) {
+ (*env)->SetObjectArrayElement(env, jarray, i + offset, tmp_string);
+ }
}
}
}
@@ -924,3 +997,99 @@
wcscpy(ret, fixes[!prefix][!positive][style][pattern]);
}
+
+int enumCalendarInfoWrapper(const jchar *langtag, CALID calid, CALTYPE type, LPWSTR buf, int buflen) {
+ if (pEnumCalendarInfoExEx) {
+ if (wcscmp(L"und", (LPWSTR)langtag) == 0) {
+ // defaults to "en"
+ return pEnumCalendarInfoExEx(&EnumCalendarInfoProc, L"en",
+ calid, NULL, type, (LPARAM)buf);
+ } else {
+ return pEnumCalendarInfoExEx(&EnumCalendarInfoProc, langtag,
+ calid, NULL, type, (LPARAM)buf);
+ }
+ } else {
+ return 0;
+ }
+}
+
+BOOL CALLBACK EnumCalendarInfoProc(LPWSTR lpCalInfoStr, CALID calid, LPWSTR lpReserved, LPARAM lParam) {
+ wcscat_s((LPWSTR)lParam, BUFLEN, lpCalInfoStr);
+ wcscat_s((LPWSTR)lParam, BUFLEN, L",");
+ return TRUE;
+}
+
+jobjectArray getErasImpl(JNIEnv *env, jstring jlangtag, jint calid, jint style, jobjectArray eras) {
+ const jchar * langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
+ WCHAR buf[BUFLEN];
+ jobjectArray ret = eras;
+ CALTYPE type;
+
+ CHECK_NULL_RETURN(langtag, ret);
+
+ buf[0] = '\0';
+ if (style & CALENDAR_STYLE_SHORT_MASK) {
+ type = CAL_SABBREVERASTRING;
+ } else {
+ type = CAL_SERASTRING;
+ }
+
+ if (calid < 0) {
+ calid = getCalendarID(langtag);
+ }
+
+ if (calid != -1 && enumCalendarInfoWrapper(langtag, calid, type, buf, BUFLEN)) {
+ // format in buf: "era0,era1,era2," where era0 is the current one
+ int eraCount;
+ LPWSTR current;
+ jsize array_length;
+
+ for(eraCount = 0, current = buf; *current != '\0'; current++) {
+ if (*current == L',') {
+ eraCount ++;
+ }
+ }
+
+ if (eras != NULL) {
+ array_length = (*env)->GetArrayLength(env, eras);
+ } else {
+ // +1 for the "before" era, e.g., BC, which Windows does not return.
+ array_length = (jsize)eraCount + 1;
+ ret = (*env)->NewObjectArray(env, array_length,
+ (*env)->FindClass(env, "java/lang/String"), NULL);
+ }
+
+ if (ret != NULL) {
+ int eraIndex;
+ LPWSTR era;
+
+ for(eraIndex = 0, era = current = buf; eraIndex < eraCount; era = current, eraIndex++) {
+ while (*current != L',') {
+ current++;
+ }
+ *current++ = '\0';
+
+ if (eraCount - eraIndex < array_length &&
+ *era != '\0') {
+ (*env)->SetObjectArrayElement(env, ret,
+ (jsize)(eraCount - eraIndex),
+ (*env)->NewString(env, era, (jsize)wcslen(era)));
+ }
+ }
+
+ // Hack for the Japanese Imperial Calendar to insert Gregorian era for
+ // "Before Meiji"
+ if (calid == CAL_JAPAN) {
+ buf[0] = '\0';
+ if (enumCalendarInfoWrapper(langtag, CAL_GREGORIAN, type, buf, BUFLEN)) {
+ jsize len = (jsize)wcslen(buf);
+ buf[--len] = '\0'; // remove the last ','
+ (*env)->SetObjectArrayElement(env, ret, 0, (*env)->NewString(env, buf, len));
+ }
+ }
+ }
+ }
+
+ (*env)->ReleaseStringChars(env, jlangtag, langtag);
+ return ret;
+}
--- a/jdk/src/java.sql/share/classes/java/sql/Statement.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/java.sql/share/classes/java/sql/Statement.java Tue Jan 05 10:38:10 2016 -0800
@@ -1582,4 +1582,43 @@
return len >= 1 && len <= 128
&& Pattern.compile("[\\p{Alpha}][\\p{Alnum}_]*").matcher(identifier).matches();
}
+
+ /**
+ * Returns a {@code String} representing a National Character Set Literal
+ * enclosed in single quotes and prefixed with a upper case letter N.
+ * Any occurrence of a single quote within the string will be replaced
+ * by two single quotes.
+ *
+ * <blockquote>
+ * <table border = 1 cellspacing=0 cellpadding=5 >
+ * <caption>Examples of the conversion:</caption>
+ * <tr>
+ * <th>Value</th>
+ * <th>Result</th>
+ * </tr>
+ * <tr> <td align='center'>Hello</td> <td align='center'>N'Hello'</td> </tr>
+ * <tr> <td align='center'>G'Day</td> <td align='center'>N'G''Day'</td> </tr>
+ * <tr> <td align='center'>'G''Day'</td>
+ * <td align='center'>N'''G''''Day'''</td> </tr>
+ * <tr> <td align='center'>I'''M</td> <td align='center'>N'I''''''M'</td>
+ * <tr> <td align='center'>N'Hello'</td> <td align='center'>N'N''Hello'''</td> </tr>
+ *
+ * </table>
+ * </blockquote>
+ * @implNote
+ * JDBC driver implementations may need to provide their own implementation
+ * of this method in order to meet the requirements of the underlying
+ * datasource. An implementation of enquoteNCharLiteral may accept a different
+ * set of characters than that accepted by the same drivers implementation of
+ * enquoteLiteral.
+ * @param val a character string
+ * @return the result of replacing every single quote character in the
+ * argument by two single quote characters where this entire result is
+ * then prefixed with 'N'.
+ * @throws NullPointerException if val is {@code null}
+ * @throws SQLException if a database access error occurs
+ */
+ default String enquoteNCharLiteral(String val) throws SQLException {
+ return "N'" + val.replace("'", "''") + "'";
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/JarFileSystem.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nio.zipfs;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+/**
+ * Adds aliasing to ZipFileSystem to support multi-release jar files. An alias map
+ * is created by {@link JarFileSystem#createVersionedLinks(int)}. The map is then
+ * consulted when an entry is looked up in {@link JarFileSystem#getEntry(byte[])}
+ * to determine if the entry has a corresponding versioned entry. If so, the
+ * versioned entry is returned.
+ *
+ * @author Steve Drach
+ */
+
+class JarFileSystem extends ZipFileSystem {
+ private Function<byte[],byte[]> lookup;
+
+ @Override
+ Entry getEntry(byte[] path) throws IOException {
+ // check for an alias to a versioned entry
+ byte[] versionedPath = lookup.apply(path);
+ return versionedPath == null ? super.getEntry(path) : super.getEntry(versionedPath);
+ }
+
+ JarFileSystem(ZipFileSystemProvider provider, Path zfpath, Map<String,?> env)
+ throws IOException {
+ super(provider, zfpath, env);
+ lookup = path -> path; // lookup needs to be set before isMultiReleaseJar is called
+ // because it eventually calls getEntry
+ if (isMultiReleaseJar()) {
+ int version;
+ Object o = env.get("multi-release");
+ if (o instanceof String) {
+ String s = (String)o;
+ if (s.equals("runtime")) {
+ version = sun.misc.Version.jdkMajorVersion(); // fixme waiting for jdk.util.Version
+ } else {
+ version = Integer.parseInt(s);
+ }
+ } else if (o instanceof Integer) {
+ version = (Integer)o;
+ } else if (false /*o instanceof Version*/) { // fixme waiting for jdk.util.Version
+// version = ((Version)o).major();
+ } else {
+ throw new IllegalArgumentException("env parameter must be String, Integer, "
+ + "or Version");
+ }
+ lookup = createVersionedLinks(version < 0 ? 0 : version);
+ setReadOnly();
+ }
+ }
+
+ private boolean isMultiReleaseJar() {
+ try (InputStream is = newInputStream(getBytes("META-INF/MANIFEST.MF"))) {
+ return (new Manifest(is)).getMainAttributes()
+ .containsKey(new Attributes.Name("Multi-Release"));
+ // fixme change line above after JarFile integration to contain Attributes.Name.MULTI_RELEASE
+ } catch (IOException x) {
+ return false;
+ }
+ }
+
+ /**
+ * create a map of aliases for versioned entries, for example:
+ * version/PackagePrivate.class -> META-INF/versions/9/version/PackagePrivate.class
+ * version/PackagePrivate.java -> META-INF/versions/9/version/PackagePrivate.java
+ * version/Version.class -> META-INF/versions/10/version/Version.class
+ * version/Version.java -> META-INF/versions/10/version/Version.java
+ *
+ * then wrap the map in a function that getEntry can use to override root
+ * entry lookup for entries that have corresponding versioned entries
+ */
+ private Function<byte[],byte[]> createVersionedLinks(int version) {
+ HashMap<IndexNode,byte[]> aliasMap = new HashMap<>();
+ getVersionMap(version, getInode(getBytes("META-INF/versions"))).values()
+ .forEach(versionNode -> { // for each META-INF/versions/{n} directory
+ // put all the leaf inodes, i.e. entries, into the alias map
+ // possibly shadowing lower versioned entries
+ walk(versionNode, entryNode -> {
+ byte[] rootName = getRootName(versionNode, entryNode);
+ if (rootName != null) {
+ IndexNode rootNode = getInode(rootName);
+ if (rootNode == null) { // no matching root node, make a virtual one
+ rootNode = IndexNode.keyOf(rootName);
+ }
+ aliasMap.put(rootNode, entryNode.name);
+ }
+ });
+ });
+ return path -> aliasMap.get(IndexNode.keyOf(path));
+ }
+
+ /**
+ * create a sorted version map of version -> inode, for inodes <= max version
+ * 9 -> META-INF/versions/9
+ * 10 -> META-INF/versions/10
+ */
+ private TreeMap<Integer, IndexNode> getVersionMap(int version, IndexNode metaInfVersions) {
+ TreeMap<Integer,IndexNode> map = new TreeMap<>();
+ IndexNode child = metaInfVersions.child;
+ while (child != null) {
+ Integer key = getVersion(child.name, metaInfVersions.name.length);
+ if (key != null && key <= version) {
+ map.put(key, child);
+ }
+ child = child.sibling;
+ }
+ return map;
+ }
+
+ /**
+ * extract the integer version number -- META-INF/versions/9 returns 9
+ */
+ private Integer getVersion(byte[] name, int offset) {
+ try {
+ return Integer.parseInt(getString(Arrays.copyOfRange(name, offset, name.length-1)));
+ } catch (NumberFormatException x) {
+ // ignore this even though it might indicate issues with the JAR structure
+ return null;
+ }
+ }
+
+ /**
+ * walk the IndexNode tree processing all leaf nodes
+ */
+ private void walk(IndexNode inode, Consumer<IndexNode> process) {
+ if (inode == null) return;
+ if (inode.isDir()) {
+ walk(inode.child, process);
+ } else {
+ process.accept(inode);
+ walk(inode.sibling, process);
+ }
+ }
+
+ /**
+ * extract the root name from a versioned entry name
+ * given inode for META-INF/versions/9/foo/bar.class
+ * and prefix META-INF/versions/9/
+ * returns foo/bar.class
+ */
+ private byte[] getRootName(IndexNode prefix, IndexNode inode) {
+ int offset = prefix.name.length;
+ byte[] fullName = inode.name;
+ return Arrays.copyOfRange(fullName, offset, fullName.length);
+ }
+}
--- a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java Tue Jan 05 10:38:10 2016 -0800
@@ -155,6 +155,10 @@
throw new ReadOnlyFileSystemException();
}
+ void setReadOnly() {
+ this.readOnly = true;
+ }
+
@Override
public Iterable<Path> getRootDirectories() {
ArrayList<Path> pathArr = new ArrayList<>();
@@ -320,7 +324,7 @@
beginRead();
try {
ensureOpen();
- e = getEntry0(path);
+ e = getEntry(path);
if (e == null) {
IndexNode inode = getInode(path);
if (inode == null)
@@ -342,7 +346,7 @@
beginWrite();
try {
ensureOpen();
- Entry e = getEntry0(path); // ensureOpen checked
+ Entry e = getEntry(path); // ensureOpen checked
if (e == null)
throw new NoSuchFileException(getString(path));
if (e.type == Entry.CEN)
@@ -445,7 +449,7 @@
beginWrite();
try {
ensureOpen();
- Entry eSrc = getEntry0(src); // ensureOpen checked
+ Entry eSrc = getEntry(src); // ensureOpen checked
if (eSrc == null)
throw new NoSuchFileException(getString(src));
if (eSrc.isDir()) { // spec says to create dst dir
@@ -460,7 +464,7 @@
else if (opt == COPY_ATTRIBUTES)
hasCopyAttrs = true;
}
- Entry eDst = getEntry0(dst);
+ Entry eDst = getEntry(dst);
if (eDst != null) {
if (!hasReplace)
throw new FileAlreadyExistsException(getString(dst));
@@ -521,7 +525,7 @@
beginRead(); // only need a readlock, the "update()" will
try { // try to obtain a writelock when the os is
ensureOpen(); // being closed.
- Entry e = getEntry0(path);
+ Entry e = getEntry(path);
if (e != null) {
if (e.isDir() || hasCreateNew)
throw new FileAlreadyExistsException(getString(path));
@@ -550,7 +554,7 @@
beginRead();
try {
ensureOpen();
- Entry e = getEntry0(path);
+ Entry e = getEntry(path);
if (e == null)
throw new NoSuchFileException(getString(path));
if (e.isDir())
@@ -592,7 +596,7 @@
newOutputStream(path, options.toArray(new OpenOption[0])));
long leftover = 0;
if (options.contains(StandardOpenOption.APPEND)) {
- Entry e = getEntry0(path);
+ Entry e = getEntry(path);
if (e != null && e.size >= 0)
leftover = e.size;
}
@@ -644,7 +648,7 @@
beginRead();
try {
ensureOpen();
- Entry e = getEntry0(path);
+ Entry e = getEntry(path);
if (e == null || e.isDir())
throw new NoSuchFileException(getString(path));
final ReadableByteChannel rbc =
@@ -714,7 +718,7 @@
beginRead();
try {
ensureOpen();
- Entry e = getEntry0(path);
+ Entry e = getEntry(path);
if (forWrite) {
checkWritable();
if (e == null) {
@@ -855,7 +859,7 @@
private Path getTempPathForEntry(byte[] path) throws IOException {
Path tmpPath = createTempFileInSameDirectoryAs(zfpath);
if (path != null) {
- Entry e = getEntry0(path);
+ Entry e = getEntry(path);
if (e != null) {
try (InputStream is = newInputStream(path)) {
Files.copy(is, tmpPath, REPLACE_EXISTING);
@@ -939,7 +943,7 @@
private long getDataPos(Entry e) throws IOException {
if (e.locoff == -1) {
- Entry e2 = getEntry0(e.name);
+ Entry e2 = getEntry(e.name);
if (e2 == null)
throw new ZipException("invalid loc for entry <" + e.name + ">");
e.locoff = e2.locoff;
@@ -1325,7 +1329,7 @@
//System.out.printf("->sync(%s) done!%n", toString());
}
- private IndexNode getInode(byte[] path) {
+ IndexNode getInode(byte[] path) {
if (path == null)
throw new NullPointerException("path");
IndexNode key = IndexNode.keyOf(path);
@@ -1340,7 +1344,7 @@
return inode;
}
- private Entry getEntry0(byte[] path) throws IOException {
+ Entry getEntry(byte[] path) throws IOException {
IndexNode inode = getInode(path);
if (inode instanceof Entry)
return (Entry)inode;
@@ -2096,7 +2100,7 @@
pos += (LOCHDR + nlen + elen);
if ((flag & FLAG_DATADESCR) != 0) {
// Data Descriptor
- Entry e = zipfs.getEntry0(name); // get the size/csize from cen
+ Entry e = zipfs.getEntry(name); // get the size/csize from cen
if (e == null)
throw new ZipException("loc: name not found in cen");
size = e.size;
--- a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystemProvider.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystemProvider.java Tue Jan 05 10:38:10 2016 -0800
@@ -100,7 +100,11 @@
}
ZipFileSystem zipfs = null;
try {
- zipfs = new ZipFileSystem(this, path, env);
+ if (env.containsKey("multi-release")) {
+ zipfs = new JarFileSystem(this, path, env);
+ } else {
+ zipfs = new ZipFileSystem(this, path, env);
+ }
} catch (ZipException ze) {
String pname = path.toString();
if (pname.endsWith(".zip") || pname.endsWith(".jar"))
@@ -124,8 +128,14 @@
throw new UnsupportedOperationException();
}
ensureFile(path);
- try {
- return new ZipFileSystem(this, path, env);
+ try {
+ ZipFileSystem zipfs;
+ if (env.containsKey("multi-release")) {
+ zipfs = new JarFileSystem(this, path, env);
+ } else {
+ zipfs = new ZipFileSystem(this, path, env);
+ }
+ return zipfs;
} catch (ZipException ze) {
String pname = path.toString();
if (pname.endsWith(".zip") || pname.endsWith(".jar"))
--- a/jdk/test/java/lang/ref/CleanerTest.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/test/java/lang/ref/CleanerTest.java Tue Jan 05 10:38:10 2016 -0800
@@ -28,9 +28,9 @@
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.Objects;
-import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -38,15 +38,21 @@
import jdk.internal.misc.CleanerImpl.WeakCleanable;
import jdk.internal.misc.CleanerImpl.SoftCleanable;
+import sun.hotspot.WhiteBox;
+
import org.testng.Assert;
import org.testng.TestNG;
import org.testng.annotations.Test;
/*
* @test
- * @library /lib/testlibrary
+ * @library /lib/testlibrary /test/lib
+ * @build sun.hotspot.WhiteBox
* @modules java.base/jdk.internal.misc
- * @run testng/othervm -Xmx4m CleanerTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run testng/othervm
+ * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
+ * -verbose:gc -Xmx4m CleanerTest
*/
@Test
@@ -54,6 +60,9 @@
// A common CleaningService used by the test for notifications
static final Cleaner COMMON = Cleaner.create();
+ // Access to WhiteBox utilities
+ static final WhiteBox whitebox = WhiteBox.getWhiteBox();
+
/**
* Test that sequences of the various actions on a Reference
* and on the Cleanable instance have the desired result.
@@ -265,50 +274,29 @@
}
/**
- * Check a set of semaphores having been released by cleanup handlers.
+ * Check a semaphore having been released by cleanup handler.
* Force a number of GC cycles to give the GC a chance to process
- * all the References and for the cleanup actions to be run.
+ * the Reference and for the cleanup action to be run.
*
- * @param semaphore a varargs list of Semaphores
- * @return true if all of the semaphores have at least 1 permit,
- * false otherwise.
+ * @param semaphore a Semaphore
+ * @return true if the semaphores has 1 permit, false otherwise.
*/
- static boolean checkCleaned(Semaphore... semaphore) {
- long[] cycles = new long[semaphore.length];
- long total = 0;
- for (int cycle = 0; cycle < 20; cycle++) {
- for (int i = 0; i < semaphore.length; i++) {
- long count = semaphore[i].availablePermits();
- if (count > 0 && cycles[i] == 0) {
- System.out.printf(" Cleanable[%d] cleaned in cycle: %d%n", i, cycle);
- cycles[i] = cycle;
- total += 1;
+ static boolean checkCleaned(Semaphore semaphore) {
+ int cycle = 0;
+ for (; cycle < 3; cycle++) {
+ try {
+ if (semaphore.tryAcquire(10L, TimeUnit.MILLISECONDS)) {
+ System.out.printf(" Cleanable cleaned in cycle: %d%n", cycle);
+ return true;
}
- }
-
- if (total == semaphore.length) {
- System.out.printf(" All cleanups done in cycle: %d, total: %d%n",
- cycle, total);
- for (int i = 0; i < semaphore.length; i++) {
- long count = semaphore[i].availablePermits();
- Assert.assertEquals(count, 1,
- "Cleanable invoked more than once, semaphore " + i);
- }
- return true; // all references freed
+ } catch (InterruptedException ie) {
+ // retry in outer loop
}
// Force GC
- memoryPressure();
+ whitebox.fullGC();
}
- // Not all objects have been cleaned
-
- for (int i = 0; i < semaphore.length; i++) {
- if (cycles[i] != 0) {
- System.out.printf(" Cleanable[%d] cleaned in cycle: %d%n", i, cycles[i]);
- } else {
- System.out.printf(" Cleanable[%d] not cleaned%n", i);
- }
- }
-
+ // Object has not been cleaned
+ System.out.printf(" Cleanable not cleaned%n");
return false; // Failing result
}
@@ -457,24 +445,6 @@
}
/**
- * MemoryPressure allocates memory to force a gc and to clear SoftReferences.
- */
- static void memoryPressure() {
- SoftReference<Object> soft = new SoftReference<>(new Object(), null);
- Vector<Object> root = new Vector<>();
- try {
- long free = 0;
- while (soft.get() != null) {
- long[] extra = new long[50_000];
- root.addElement(extra);
- }
- } catch (OutOfMemoryError mem) {
- // ignore
- root = null;
- }
- }
-
- /**
* CleanableCase encapsulates the objects used for a test.
* The reference to the object is not held directly,
* but in a Reference object that can be cleared.
--- a/jdk/test/java/net/NetworkInterface/NetworkInterfaceStreamTest.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/test/java/net/NetworkInterface/NetworkInterfaceStreamTest.java Tue Jan 05 10:38:10 2016 -0800
@@ -85,13 +85,15 @@
}
private Stream<NetworkInterface> allNetworkInterfaces() throws SocketException {
- return NetworkInterface.networkInterfaces().flatMap(this::allSubNetworkInterfaces);
+ return NetworkInterface.networkInterfaces()
+ .filter(ni -> isIncluded(ni))
+ .flatMap(this::allSubNetworkInterfaces);
}
private Stream<NetworkInterface> allSubNetworkInterfaces(NetworkInterface ni) {
return Stream.concat(
Stream.of(ni),
- ni.subInterfaces().flatMap(this::allSubNetworkInterfaces));
+ ni.subInterfaces().filter(sni -> isIncluded(sni)).flatMap(this::allSubNetworkInterfaces));
}
@Test
@@ -129,7 +131,9 @@
Collection<NetworkInterface> nis = Collections.list(NetworkInterface.getNetworkInterfaces());
Collection<InetAddress> expected = new ArrayList<>();
for (NetworkInterface ni : nis) {
- expected.addAll(Collections.list(ni.getInetAddresses()));
+ if (isIncluded(ni)) {
+ expected.addAll(Collections.list(ni.getInetAddresses()));
+ }
}
withData(TestData.Factory.ofSupplier("All inet addresses", ss))
.stream(s -> s)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/WatchService/UpdateInterference.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8145981
+ * @summary LinuxWatchService sometimes reports inotify events against wrong directory
+ * @run main UpdateInterference
+ */
+import java.io.IOException;
+import java.nio.file.*;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import static java.nio.file.StandardWatchEventKinds.*;
+
+public class UpdateInterference {
+ public static void main(String[] args) throws IOException, InterruptedException {
+ final Path root = Files.createTempDirectory("test");
+ final Path foo = root.resolve("foo");
+ final Path bar = root.resolve("bar");
+ final Path baz = root.resolve("baz");
+
+ Files.createDirectory(foo);
+ Files.createDirectory(bar);
+ Files.createDirectory(baz);
+
+ final WatchService watcher = root.getFileSystem().newWatchService();
+ final WatchKey fooKey = foo.register(watcher, ENTRY_CREATE);
+ final WatchKey barKey = bar.register(watcher, ENTRY_CREATE);
+
+ new Thread() {
+ { setDaemon(true); }
+
+ @Override
+ public void run() {
+ while (true) {
+ try {
+ final Path temp = Files.createTempFile(foo, "temp", ".tmp");
+ Files.delete(temp);
+ Thread.sleep(10);
+ } catch (IOException | InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }.start();
+
+ new Thread() {
+ { setDaemon(true); }
+
+ @Override
+ public void run() {
+ WatchKey bazKeys[] = new WatchKey[32];
+ while (true) {
+ try {
+ for( int i = 0; i < bazKeys.length; i++) {
+ bazKeys[i] = baz.register(watcher, ENTRY_CREATE);
+ }
+ for( int i = 0; i < bazKeys.length; i++) {
+ bazKeys[i].cancel();
+ }
+ Thread.sleep(1);
+ } catch (IOException | InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }.start();
+
+ long time = System.currentTimeMillis();
+ while ((System.currentTimeMillis() - time) < 15000) {
+ final WatchKey key = watcher.poll(60, TimeUnit.SECONDS);
+ if (key == null) continue;
+
+ if (key != fooKey) {
+ List<WatchEvent<?>> pollEvents = key.pollEvents();
+ for (WatchEvent<?> watchEvent : pollEvents) {
+ System.out.println(watchEvent.count() + " " +
+ watchEvent.kind() + " " +
+ watchEvent.context());
+ }
+ throw new RuntimeException("Event received for unexpected key");
+ }
+ key.reset();
+ }
+ }
+}
+
--- a/jdk/test/java/sql/testng/test/sql/StatementTests.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/test/java/sql/testng/test/sql/StatementTests.java Tue Jan 05 10:38:10 2016 -0800
@@ -65,7 +65,7 @@
* enquoteLiteral is null
*/
@Test(expectedExceptions = NullPointerException.class)
- public void test01() throws SQLException {
+ public void test01() throws SQLException {
stmt.enquoteLiteral(null);
}
@@ -110,7 +110,7 @@
}
/*
- * Validate a NullPointerException is thrown is the string passed to
+ * Validate a NullPointerException is thrown if the string passed to
* isSimpleIdentifier is null
*/
@Test(expectedExceptions = NullPointerException.class)
@@ -120,6 +120,24 @@
}
/*
+ * Verify that enquoteLiteral creates a valid literal and converts every
+ * single quote to two single quotes
+ */
+ @Test(dataProvider = "validEnquotedNCharLiteralValues")
+ public void test07(String s, String expected) throws SQLException {
+ assertEquals(stmt.enquoteNCharLiteral(s), expected);
+ }
+
+ /*
+ * Validate a NullPointerException is thrown if the string passed to
+ * enquoteNCharLiteral is null
+ */
+ @Test(expectedExceptions = NullPointerException.class)
+ public void test08() throws SQLException {
+ stmt.enquoteNCharLiteral(null);
+ }
+
+ /*
* DataProvider used to provide strings that will be used to validate
* that enquoteLiteral converts a string to a literal and every instance of
* a single quote will be converted into two single quotes in the literal.
@@ -169,8 +187,7 @@
{"\"Hel\"lo\"", true},
{"Hello" + '\0', false},
{"", false},
- {maxIdentifier + 'a', false},
- };
+ {maxIdentifier + 'a', false},};
}
/*
@@ -194,4 +211,22 @@
{"", false},};
}
+ /*
+ * DataProvider used to provide strings that will be used to validate
+ * that enquoteNCharLiteral converts a string to a National Character
+ * literal and every instance of
+ * a single quote will be converted into two single quotes in the literal.
+ */
+ @DataProvider(name = "validEnquotedNCharLiteralValues")
+ protected Object[][] validEnquotedNCharLiteralValues() {
+ return new Object[][]{
+ {"Hello", "N'Hello'"},
+ {"G'Day", "N'G''Day'"},
+ {"'G''Day'", "N'''G''''Day'''"},
+ {"I'''M", "N'I''''''M'"},
+ {"N'Hello'", "N'N''Hello'''"},
+ {"The Dark Knight", "N'The Dark Knight'"}
+
+ };
+ }
}
--- a/jdk/test/java/time/tck/java/time/TCKDuration.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/test/java/time/tck/java/time/TCKDuration.java Tue Jan 05 10:38:10 2016 -0800
@@ -2893,6 +2893,9 @@
{-1, 0, "PT-1S"},
{-1, 1000, "PT-0.999999S"},
{-1, 900000000, "PT-0.1S"},
+ {-60, 100_000_000, "PT-59.9S"},
+ {-59, -900_000_000, "PT-59.9S"},
+ {-60, -100_000_000, "PT-1M-0.1S"},
{Long.MAX_VALUE, 0, "PT" + (Long.MAX_VALUE / 3600) + "H" +
((Long.MAX_VALUE % 3600) / 60) + "M" + (Long.MAX_VALUE % 60) + "S"},
{Long.MIN_VALUE, 0, "PT" + (Long.MIN_VALUE / 3600) + "H" +
--- a/jdk/test/java/time/tck/java/time/TCKLocalDate.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/test/java/time/tck/java/time/TCKLocalDate.java Tue Jan 05 10:38:10 2016 -0800
@@ -2157,6 +2157,31 @@
}
//-----------------------------------------------------------------------
+ // toEpochSecond
+ //-----------------------------------------------------------------------
+ @DataProvider(name="epochSecond")
+ Object[][] provider_toEpochSecond() {
+ return new Object[][] {
+ {LocalDate.of(1858, 11, 17).toEpochSecond(LocalTime.MIDNIGHT, OFFSET_PONE), -3506720400L},
+ {LocalDate.of(1, 1, 1).toEpochSecond(LocalTime.NOON, OFFSET_PONE), -62135557200L},
+ {LocalDate.of(1995, 9, 27).toEpochSecond(LocalTime.of(5, 30), OFFSET_PTWO), 812172600L},
+ {LocalDate.of(1970, 1, 1).toEpochSecond(LocalTime.MIDNIGHT, OFFSET_MTWO), 7200L},
+ {LocalDate.of(-1, 12, 31).toEpochSecond(LocalTime.NOON, OFFSET_PONE), -62167266000L},
+ {LocalDate.of(1, 1, 1).toEpochSecond(LocalTime.MIDNIGHT, OFFSET_PONE),
+ Instant.ofEpochSecond(-62135600400L).getEpochSecond()},
+ {LocalDate.of(1995, 9, 27).toEpochSecond(LocalTime.NOON, OFFSET_PTWO),
+ Instant.ofEpochSecond(812196000L).getEpochSecond()},
+ {LocalDate.of(1995, 9, 27).toEpochSecond(LocalTime.of(5, 30), OFFSET_MTWO),
+ LocalDateTime.of(1995, 9, 27, 5, 30).toEpochSecond(OFFSET_MTWO)},
+ };
+ }
+
+ @Test(dataProvider="epochSecond")
+ public void test_toEpochSecond(long actual, long expected) {
+ assertEquals(actual, expected);
+ }
+
+ //-----------------------------------------------------------------------
// compareTo()
//-----------------------------------------------------------------------
@Test
--- a/jdk/test/java/time/tck/java/time/TCKLocalTime.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/test/java/time/tck/java/time/TCKLocalTime.java Tue Jan 05 10:38:10 2016 -0800
@@ -2433,6 +2433,32 @@
}
}
+ //-----------------------------------------------------------------------
+ // toEpochSecond()
+ //--------------------------------------------------------------------------
+ @DataProvider(name="epochSecond")
+ Object[][] provider__toEpochSecond() {
+ return new Object[][] {
+ {LocalTime.of(0, 0).toEpochSecond(LocalDate.of(1970, 1, 1), OFFSET_PTWO), -7200L},
+ {LocalTime.of(11, 30).toEpochSecond(LocalDate.of(1965, 12, 31), OFFSET_PTWO), -126282600L},
+ {LocalTime.of(11, 30).toEpochSecond(LocalDate.of(1995, 5, 3), OFFSET_MTWO), 799507800L},
+ {LocalTime.of(0, 0).toEpochSecond(LocalDate.of(1970, 1, 1), OFFSET_PTWO),
+ Instant.ofEpochSecond(-7200).getEpochSecond()},
+ {LocalTime.of(11, 30).toEpochSecond(LocalDate.of(1969, 12, 31), OFFSET_MTWO),
+ Instant.ofEpochSecond(-37800L).getEpochSecond()},
+ {LocalTime.of(11, 30).toEpochSecond(LocalDate.of(1970, 1, 1), OFFSET_PTWO),
+ LocalDateTime.of(1970, 1, 1, 11, 30).toEpochSecond(OFFSET_PTWO)},
+ };
+ }
+
+ @Test(dataProvider="epochSecond")
+ public void test_toEpochSecond(long actual, long expected) {
+ assertEquals(actual, expected);
+ }
+
+ //-----------------------------------------------------------------------
+ // toSecondOfDay_fromNanoOfDay_symmetry()
+ //-----------------------------------------------------------------------
@Test
public void test_toSecondOfDay_fromNanoOfDay_symmetry() {
LocalTime t = LocalTime.of(0, 0);
--- a/jdk/test/java/time/tck/java/time/TCKOffsetTime.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/test/java/time/tck/java/time/TCKOffsetTime.java Tue Jan 05 10:38:10 2016 -0800
@@ -134,6 +134,7 @@
private static final ZoneId ZONE_GAZA = ZoneId.of("Asia/Gaza");
private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1);
private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2);
+ private static final ZoneOffset OFFSET_MTWO = ZoneOffset.ofHours(-2);
private static final LocalDate DATE = LocalDate.of(2008, 12, 3);
private OffsetTime TEST_11_30_59_500_PONE;
@@ -1149,6 +1150,29 @@
}
//-----------------------------------------------------------------------
+ // toEpochSecond()
+ //-----------------------------------------------------------------------
+ @DataProvider(name="epochSecond")
+ Object[][] provider_toEpochSecond() {
+ return new Object[][] {
+ {OffsetTime.of(0, 0, 0, 0, OFFSET_PTWO).toEpochSecond(LocalDate.of(1970, 1, 1)), -7200L},
+ {OffsetTime.of(11, 30, 0, 0, OFFSET_MTWO).toEpochSecond(LocalDate.of(1995, 9, 27)), 812208600L},
+ {OffsetTime.of(0, 0, 0, 0, OFFSET_PONE).toEpochSecond(LocalDate.of(1970, 1, 1)),
+ Instant.ofEpochSecond(-3600).getEpochSecond()},
+ {OffsetTime.of(11, 30, 0, 0, OFFSET_PTWO).toEpochSecond(LocalDate.of(1965, 12, 31)),
+ Instant.ofEpochSecond(-126282600L).getEpochSecond()},
+ {OffsetTime.of(11, 30, 0, 0, OFFSET_MTWO).toEpochSecond(LocalDate.of(1970, 1, 1)),
+ OffsetDateTime.of(LocalDate.of(1970, 1, 1), LocalTime.of(11, 30), OFFSET_MTWO)
+ .toEpochSecond()},
+ };
+ }
+
+ @Test(dataProvider="epochSecond")
+ public void test_toEpochSecond(long actual, long expected) {
+ assertEquals(actual, expected);
+ }
+
+ //-----------------------------------------------------------------------
// compareTo()
//-----------------------------------------------------------------------
@Test
--- a/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java Tue Jan 05 10:38:10 2016 -0800
@@ -751,7 +751,7 @@
{"2012-06-30T12:30:40Z[GMT]", 2012, 6, 30, 12, 30, 40, 0, "GMT"},
{"2012-06-30T12:30:40Z[UT]", 2012, 6, 30, 12, 30, 40, 0, "UT"},
{"2012-06-30T12:30:40Z[UTC]", 2012, 6, 30, 12, 30, 40, 0, "UTC"},
- {"2012-06-30T12:30:40+01:00[Z]", 2012, 6, 30, 12, 30, 40, 0, "Z"},
+ {"2012-06-30T12:30:40+01:00[Z]", 2012, 6, 30, 11, 30, 40, 0, "Z"},
{"2012-06-30T12:30:40+01:00[+01:00]", 2012, 6, 30, 12, 30, 40, 0, "+01:00"},
{"2012-06-30T12:30:40+01:00[GMT+01:00]", 2012, 6, 30, 12, 30, 40, 0, "GMT+01:00"},
{"2012-06-30T12:30:40+01:00[UT+01:00]", 2012, 6, 30, 12, 30, 40, 0, "UT+01:00"},
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/time/tck/java/time/format/TCKDTFParsedInstant.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tck.java.time.format;
+
+import static org.testng.AssertJUnit.assertEquals;
+
+import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * Testing DateTimeFormatter Parsing with 4 different test conditions:
+ * 1. When Zone and Offset not provided
+ * 2. When Zone and Offset provided
+ * 3. When Offset is not provided and Zone is provided
+ * 4. When Zone is not provided and Offset is provided
+ */
+
+@Test
+public class TCKDTFParsedInstant {
+
+ private static final ZoneId EUROPE_BERLIN = ZoneId.of("Europe/Berlin");
+ private static final ZoneId ASIA_ISTANBUL = ZoneId.of("Asia/Istanbul");
+
+ private DateTimeFormatter dtFormatter;
+ private ZonedDateTime zdt1, zdt2;
+ private LocalDateTime ldt1;
+ private OffsetDateTime odt1;
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ dtFormatter = DateTimeFormatter.ISO_ZONED_DATE_TIME;
+ }
+
+ @DataProvider(name="parseWithoutZoneWithoutOffset")
+ Object[][] data_parse_WithoutOffset_WithoutZone() {
+ return new Object[][] {
+ {"1966-12-31T00:01:10", LocalDateTime.of(1966, 12, 31, 0, 1, 10)},
+ {"1970-01-01T00:00:00", LocalDateTime.of(1970, 1, 1, 0, 0, 0)},
+ {"2004-02-29T00:30:00", LocalDateTime.of(2004, 2, 29, 0, 30, 0)},
+ {"2015-12-31T23:59:59", LocalDateTime.of(2015, 12, 31, 23, 59, 59)}
+ };
+ }
+
+ @Test(dataProvider="parseWithoutZoneWithoutOffset")
+ public void testWithoutZoneWithoutOffset(String ldtString, LocalDateTime expectedLDT) {
+ dtFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
+ ldt1 = LocalDateTime.parse(ldtString, dtFormatter);
+ assertEquals(expectedLDT, ldt1);
+ }
+
+ @DataProvider(name="parseWithZoneWithOffset")
+ Object[][] data_parse_WithZone_WithOffset() {
+ return new Object[][] {
+ {"2012-10-28T01:45:00-02:30[Europe/Berlin]",
+ LocalDateTime.of(2012, 10, 28, 1, 45, 0, 0), ZoneOffset.of("-02:30"), EUROPE_BERLIN},
+ {"2012-10-28T01:45:00-01:00[Europe/Berlin]",
+ LocalDateTime.of(2012, 10, 28, 1, 45, 0, 0), ZoneOffset.of("-01:00"), EUROPE_BERLIN},
+ {"2012-10-28T01:45:00-00:00[Europe/Berlin]",
+ LocalDateTime.of(2012, 10, 28, 1, 45, 0, 0), ZoneOffset.of("-00:00"), EUROPE_BERLIN},
+ {"2012-10-28T01:45:00+00:00[Europe/Berlin]",
+ LocalDateTime.of(2012, 10, 28, 1, 45, 0, 0), ZoneOffset.of("+00:00"), EUROPE_BERLIN},
+ {"2012-10-28T01:45:00+01:00[Europe/Berlin]",
+ LocalDateTime.of(2012, 10, 28, 1, 45, 0, 0), ZoneOffset.of("+01:00"), EUROPE_BERLIN},
+ {"2012-10-28T01:45:00+02:00[Europe/Berlin]",
+ LocalDateTime.of(2012, 10, 28, 1, 45, 0, 0), ZoneOffset.of("+02:00"), EUROPE_BERLIN},
+ {"2012-10-28T01:45:00+03:00[Europe/Berlin]",
+ LocalDateTime.of(2012, 10, 28, 1, 45, 0, 0), ZoneOffset.of("+03:00"), EUROPE_BERLIN},
+ {"2012-10-28T02:45:00-02:30[Europe/Berlin]",
+ LocalDateTime.of(2012, 10, 28, 2, 45, 0, 0), ZoneOffset.of("-02:30"), EUROPE_BERLIN},
+ {"2012-10-28T02:45:00-01:00[Europe/Berlin]",
+ LocalDateTime.of(2012, 10, 28, 2, 45, 0, 0), ZoneOffset.of("-01:00"), EUROPE_BERLIN},
+ {"2012-10-28T02:45:00-00:00[Europe/Berlin]",
+ LocalDateTime.of(2012, 10, 28, 2, 45, 0, 0), ZoneOffset.of("-00:00"), EUROPE_BERLIN},
+ {"2012-10-28T02:45:00+00:00[Europe/Berlin]",
+ LocalDateTime.of(2012, 10, 28, 2, 45, 0, 0), ZoneOffset.of("+00:00"), EUROPE_BERLIN},
+ {"2012-10-28T02:45:00+01:00[Europe/Berlin]",
+ LocalDateTime.of(2012, 10, 28, 2, 45, 0, 0), ZoneOffset.of("+01:00"), EUROPE_BERLIN},
+ {"2012-10-28T02:45:00+02:00[Europe/Berlin]",
+ LocalDateTime.of(2012, 10, 28, 2, 45, 0, 0), ZoneOffset.of("+02:00"), EUROPE_BERLIN},
+ {"2012-10-28T02:45:00+03:00[Europe/Berlin]",
+ LocalDateTime.of(2012, 10, 28, 2, 45, 0, 0), ZoneOffset.of("+03:00"), EUROPE_BERLIN},
+ {"2012-10-28T03:45:00-02:30[Europe/Berlin]",
+ LocalDateTime.of(2012, 10, 28, 3, 45, 0, 0), ZoneOffset.of("-02:30"), EUROPE_BERLIN},
+ {"2012-10-28T03:45:00-01:00[Europe/Berlin]",
+ LocalDateTime.of(2012, 10, 28, 3, 45, 0, 0), ZoneOffset.of("-01:00"), EUROPE_BERLIN},
+ {"2012-10-28T03:45:00-00:00[Europe/Berlin]",
+ LocalDateTime.of(2012, 10, 28, 3, 45, 0, 0), ZoneOffset.of("-00:00"), EUROPE_BERLIN},
+ {"2012-10-28T03:45:00+00:00[Europe/Berlin]",
+ LocalDateTime.of(2012, 10, 28, 3, 45, 0, 0), ZoneOffset.of("+00:00"), EUROPE_BERLIN},
+ {"2012-10-28T03:45:00+01:00[Europe/Berlin]",
+ LocalDateTime.of(2012, 10, 28, 3, 45, 0, 0), ZoneOffset.of("+01:00"), EUROPE_BERLIN},
+ {"2012-10-28T03:45:00+02:00[Europe/Berlin]",
+ LocalDateTime.of(2012, 10, 28, 3, 45, 0, 0), ZoneOffset.of("+02:00"), EUROPE_BERLIN},
+ {"2012-10-28T03:45:00+03:00[Europe/Berlin]",
+ LocalDateTime.of(2012, 10, 28, 3, 45, 0, 0), ZoneOffset.of("+03:00"), EUROPE_BERLIN},
+
+ {"2012-10-28T02:45:00-02:30[Asia/Istanbul]",
+ LocalDateTime.of(2012, 10, 28, 2, 45, 0, 0), ZoneOffset.of("-02:30"), ASIA_ISTANBUL},
+ {"2012-10-28T02:45:00-01:00[Asia/Istanbul]",
+ LocalDateTime.of(2012, 10, 28, 2, 45, 0, 0), ZoneOffset.of("-01:00"), ASIA_ISTANBUL},
+ {"2012-10-28T02:45:00-00:00[Asia/Istanbul]",
+ LocalDateTime.of(2012, 10, 28, 2, 45, 0, 0), ZoneOffset.of("-00:00"), ASIA_ISTANBUL},
+ {"2012-10-28T02:45:00+00:00[Asia/Istanbul]",
+ LocalDateTime.of(2012, 10, 28, 2, 45, 0, 0), ZoneOffset.of("+00:00"), ASIA_ISTANBUL},
+ {"2012-10-28T02:45:00+01:00[Asia/Istanbul]",
+ LocalDateTime.of(2012, 10, 28, 2, 45, 0, 0), ZoneOffset.of("+01:00"), ASIA_ISTANBUL},
+ {"2012-10-28T02:45:00+02:00[Asia/Istanbul]",
+ LocalDateTime.of(2012, 10, 28, 2, 45, 0, 0), ZoneOffset.of("+02:00"), ASIA_ISTANBUL},
+ {"2012-10-28T02:45:00+03:00[Asia/Istanbul]",
+ LocalDateTime.of(2012, 10, 28, 2, 45, 0, 0), ZoneOffset.of("+03:00"), ASIA_ISTANBUL},
+ {"2012-10-28T03:45:00-02:30[Asia/Istanbul]",
+ LocalDateTime.of(2012, 10, 28, 3, 45, 0, 0), ZoneOffset.of("-02:30"), ASIA_ISTANBUL},
+ {"2012-10-28T03:45:00-01:00[Asia/Istanbul]",
+ LocalDateTime.of(2012, 10, 28, 3, 45, 0, 0), ZoneOffset.of("-01:00"), ASIA_ISTANBUL},
+ {"2012-10-28T03:45:00-00:00[Asia/Istanbul]",
+ LocalDateTime.of(2012, 10, 28, 3, 45, 0, 0), ZoneOffset.of("-00:00"), ASIA_ISTANBUL},
+ {"2012-10-28T03:45:00+00:00[Asia/Istanbul]",
+ LocalDateTime.of(2012, 10, 28, 3, 45, 0, 0), ZoneOffset.of("+00:00"), ASIA_ISTANBUL},
+ {"2012-10-28T03:45:00+01:00[Asia/Istanbul]",
+ LocalDateTime.of(2012, 10, 28, 3, 45, 0, 0), ZoneOffset.of("+01:00"), ASIA_ISTANBUL},
+ {"2012-10-28T03:45:00+02:00[Asia/Istanbul]",
+ LocalDateTime.of(2012, 10, 28, 3, 45, 0, 0), ZoneOffset.of("+02:00"), ASIA_ISTANBUL},
+ {"2012-10-28T03:45:00+03:00[Asia/Istanbul]",
+ LocalDateTime.of(2012, 10, 28, 3, 45, 0, 0), ZoneOffset.of("+03:00"), ASIA_ISTANBUL},
+ {"2012-10-28T04:45:00-02:30[Asia/Istanbul]",
+ LocalDateTime.of(2012, 10, 28, 4, 45, 0, 0), ZoneOffset.of("-02:30"), ASIA_ISTANBUL},
+ {"2012-10-28T04:45:00-01:00[Asia/Istanbul]",
+ LocalDateTime.of(2012, 10, 28, 4, 45, 0, 0), ZoneOffset.of("-01:00"), ASIA_ISTANBUL},
+ {"2012-10-28T04:45:00-00:00[Asia/Istanbul]",
+ LocalDateTime.of(2012, 10, 28, 4, 45, 0, 0), ZoneOffset.of("-00:00"), ASIA_ISTANBUL},
+ {"2012-10-28T04:45:00+00:00[Asia/Istanbul]",
+ LocalDateTime.of(2012, 10, 28, 4, 45, 0, 0), ZoneOffset.of("+00:00"), ASIA_ISTANBUL},
+ {"2012-10-28T04:45:00+01:00[Asia/Istanbul]",
+ LocalDateTime.of(2012, 10, 28, 4, 45, 0, 0), ZoneOffset.of("+01:00"), ASIA_ISTANBUL},
+ {"2012-10-28T04:45:00+02:00[Asia/Istanbul]",
+ LocalDateTime.of(2012, 10, 28, 4, 45, 0, 0), ZoneOffset.of("+02:00"), ASIA_ISTANBUL},
+ {"2012-10-28T04:45:00+03:00[Asia/Istanbul]",
+ LocalDateTime.of(2012, 10, 28, 4, 45, 0, 0), ZoneOffset.of("+03:00"), ASIA_ISTANBUL}
+ };
+ }
+
+ @Test(dataProvider="parseWithZoneWithOffset")
+ public void testWithZoneWithOffset(String zdtString, LocalDateTime ldt, ZoneOffset offset, ZoneId zone) {
+ dtFormatter = DateTimeFormatter.ISO_ZONED_DATE_TIME;
+ zdt1 = ZonedDateTime.ofInstant(ldt, offset, zone);
+ zdt2 = ZonedDateTime.parse(zdtString, dtFormatter);
+ assertEquals(zdt1, zdt2);
+ }
+
+ @DataProvider(name="parseWithZoneWithoutOffset")
+ Object[][] data_parse_WithZone_WithoutOffset() {
+ return new Object[][] {
+ {"28 Oct 00:45:00 2012 Europe/Berlin", ZonedDateTime.of(2012, 10, 28, 0, 45, 0, 0, EUROPE_BERLIN)},
+ {"28 Oct 01:45:00 2012 Europe/Berlin", ZonedDateTime.of(2012, 10, 28, 1, 45, 0, 0, EUROPE_BERLIN)},
+ {"28 Oct 02:45:00 2012 Europe/Berlin", ZonedDateTime.of(2012, 10, 28, 2, 45, 0, 0, EUROPE_BERLIN)},
+ {"28 Oct 03:45:00 2012 Europe/Berlin", ZonedDateTime.of(2012, 10, 28, 3, 45, 0, 0, EUROPE_BERLIN)},
+ {"28 Oct 04:45:00 2012 Europe/Berlin", ZonedDateTime.of(2012, 10, 28, 4, 45, 0, 0, EUROPE_BERLIN)},
+
+ {"28 Oct 01:45:00 2012 Asia/Istanbul", ZonedDateTime.of(2012, 10, 28, 1, 45, 0, 0, ASIA_ISTANBUL)},
+ {"28 Oct 02:45:00 2012 Asia/Istanbul", ZonedDateTime.of(2012, 10, 28, 2, 45, 0, 0, ASIA_ISTANBUL)},
+ {"28 Oct 03:45:00 2012 Asia/Istanbul", ZonedDateTime.of(2012, 10, 28, 3, 45, 0, 0, ASIA_ISTANBUL)},
+ {"28 Oct 04:45:00 2012 Asia/Istanbul", ZonedDateTime.of(2012, 10, 28, 4, 45, 0, 0, ASIA_ISTANBUL)},
+ {"28 Oct 05:45:00 2012 Asia/Istanbul", ZonedDateTime.of(2012, 10, 28, 5, 45, 0, 0, ASIA_ISTANBUL)}
+ };
+ }
+
+ @Test(dataProvider="parseWithZoneWithoutOffset")
+ public void testWithZoneWithoutOffset(String withZoneWithoutOffset, ZonedDateTime expectedZDT) {
+ dtFormatter = DateTimeFormatter.ofPattern("d MMM HH:mm:ss uuuu VV");
+ zdt1 = ZonedDateTime.parse(withZoneWithoutOffset, dtFormatter);
+ assertEquals(expectedZDT, zdt1);
+ }
+
+ @DataProvider(name="parseWithOffsetWithoutZone")
+ Object[][] data_parse_WithOffset_WithoutZone() {
+ return new Object[][] {
+ {"2015-12-14T00:45:00-11:30", OffsetDateTime.of(2015, 12, 14, 0, 45, 0, 0, ZoneOffset.of("-11:30"))},
+ {"2015-12-14T01:45:00-05:00", OffsetDateTime.of(2015, 12, 14, 1, 45, 0, 0, ZoneOffset.of("-05:00"))},
+ {"2015-12-14T02:45:00-00:00", OffsetDateTime.of(2015, 12, 14, 2, 45, 0, 0, ZoneOffset.of("-00:00"))},
+ {"2015-12-14T03:45:00+00:00", OffsetDateTime.of(2015, 12, 14, 3, 45, 0, 0, ZoneOffset.of("+00:00"))},
+ {"2015-12-14T04:45:00+03:30", OffsetDateTime.of(2015, 12, 14, 4, 45, 0, 0, ZoneOffset.of("+03:30"))},
+ {"2015-12-14T05:45:00+10:00", OffsetDateTime.of(2015, 12, 14, 5, 45, 0, 0, ZoneOffset.of("+10:00"))}
+ };
+ }
+
+ @Test(dataProvider="parseWithOffsetWithoutZone")
+ public void testWithOffsetWithoutZone(String odtString, OffsetDateTime expectedOTD) {
+ dtFormatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
+ odt1 = OffsetDateTime.parse(odtString, dtFormatter);
+ assertEquals(expectedOTD, odt1);
+ }
+}
--- a/jdk/test/java/util/Locale/LocaleProviders.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/test/java/util/Locale/LocaleProviders.java Tue Jan 05 10:38:10 2016 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -213,7 +213,7 @@
static void bug8013903Test() {
if (System.getProperty("os.name").startsWith("Windows")) {
Date sampleDate = new Date(0x10000000000L);
- String fallbackResult = "Heisei 16.Nov.03 (Wed) AM 11:53:47";
+ String hostResult = "\u5e73\u6210 16.11.03 (Wed) AM 11:53:47";
String jreResult = "\u5e73\u6210 16.11.03 (\u6c34) \u5348\u524d 11:53:47";
Locale l = new Locale("ja", "JP", "JP");
SimpleDateFormat sdf = new SimpleDateFormat("GGGG yyyy.MMM.dd '('E')' a hh:mm:ss", l);
@@ -227,11 +227,10 @@
result + "\", expected: \"" + jreResult);
}
} else {
- // should be FALLBACK, as Windows HOST does not return
- // display names
- if (!fallbackResult.equals(result)) {
+ // Windows display names. Subject to change if Windows changes its format.
+ if (!hostResult.equals(result)) {
throw new RuntimeException("Format failed. result: \"" +
- result + "\", expected: \"" + fallbackResult);
+ result + "\", expected: \"" + hostResult);
}
}
}
--- a/jdk/test/java/util/Locale/LocaleProviders.sh Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/test/java/util/Locale/LocaleProviders.sh Tue Jan 05 10:38:10 2016 -0800
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# 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
@@ -24,7 +24,7 @@
#
# @test
# @bug 6336885 7196799 7197573 7198834 8000245 8000615 8001440 8008577
-# 8010666 8013086 8013233 8013903 8015960 8028771 8062006
+# 8010666 8013086 8013233 8013903 8015960 8028771 8054482 8062006
# @summary tests for "java.locale.providers" system property
# @compile -XDignore.symbol.file LocaleProviders.java
# @run shell/timeout=600 LocaleProviders.sh
--- a/jdk/test/java/util/zip/ZipFile/TestZipFile.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/test/java/util/zip/ZipFile/TestZipFile.java Tue Jan 05 10:38:10 2016 -0800
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8142508
+ * @bug 8142508 8146431
* @summary Tests various ZipFile apis
* @run main/manual TestZipFile
*/
@@ -216,6 +216,13 @@
}
static void doTest0(Zip zip, ZipFile zf) throws Throwable {
+ // (0) check zero-length entry name, no AIOOBE
+ try {
+ check(zf.getEntry("") == null);;
+ } catch (Throwable t) {
+ unexpected(t);
+ }
+
List<ZipEntry> list = new ArrayList(zip.entries.keySet());
// (1) check entry list, in expected order
if (!check(Arrays.equals(
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/MBeanServer/ExceptionFactory.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.ArrayList;
+import javax.management.AttributeNotFoundException;
+import javax.management.BadAttributeValueExpException;
+import javax.management.BadBinaryOpValueExpException;
+import javax.management.BadStringOperationException;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.IntrospectionException;
+import javax.management.InvalidApplicationException;
+import javax.management.InvalidAttributeValueException;
+import javax.management.JMException;
+import javax.management.JMRuntimeException;
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanRegistrationException;
+import javax.management.MalformedObjectNameException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.OperationsException;
+import javax.management.ReflectionException;
+import javax.management.RuntimeErrorException;
+import javax.management.RuntimeMBeanException;
+import javax.management.RuntimeOperationsException;
+import javax.management.ServiceNotFoundException;
+import javax.management.StringValueExp;
+import javax.management.modelmbean.InvalidTargetObjectTypeException;
+import javax.management.modelmbean.XMLParseException;
+import javax.management.monitor.MonitorSettingException;
+import javax.management.openmbean.InvalidKeyException;
+import javax.management.openmbean.InvalidOpenTypeException;
+import javax.management.openmbean.KeyAlreadyExistsException;
+import javax.management.openmbean.OpenDataException;
+import javax.management.relation.InvalidRelationIdException;
+import javax.management.relation.InvalidRelationServiceException;
+import javax.management.relation.InvalidRelationTypeException;
+import javax.management.relation.InvalidRoleInfoException;
+import javax.management.relation.InvalidRoleValueException;
+import javax.management.relation.RelationException;
+import javax.management.relation.RelationNotFoundException;
+import javax.management.relation.RelationServiceNotRegisteredException;
+import javax.management.relation.RelationTypeNotFoundException;
+import javax.management.relation.RoleInfoNotFoundException;
+import javax.management.relation.RoleNotFoundException;
+import javax.management.remote.JMXProviderException;
+import javax.management.remote.JMXServerErrorException;
+
+/**
+ * |----- Original Description Coming From Tonga Original Source Code -------|
+ * | |
+ * | That class creates an ArrayList and fill it with an instance of each of |
+ * | the Exception class of the JMX API. |
+ * | It's dedicated to use by ExceptionTest. |
+ * |-------------------------------------------------------------------------|
+ */
+public class ExceptionFactory {
+
+ public static final ArrayList<Exception> exceptions =
+ new ArrayList<Exception>();
+
+ static {
+ String mes = "SQE";
+ exceptions.add(new AttributeNotFoundException());
+ exceptions.add(new BadAttributeValueExpException(mes));
+ exceptions.add(new BadBinaryOpValueExpException(new StringValueExp(mes)));
+ exceptions.add(new BadStringOperationException(mes));
+ exceptions.add(new InstanceAlreadyExistsException());
+ exceptions.add(new InstanceNotFoundException());
+ exceptions.add(new IntrospectionException());
+ exceptions.add(new InvalidApplicationException(mes));
+ exceptions.add(new InvalidAttributeValueException());
+ exceptions.add(new JMException());
+ exceptions.add(new JMRuntimeException());
+ exceptions.add(new ListenerNotFoundException());
+ exceptions.add(new MalformedObjectNameException());
+ exceptions.add(new MBeanException(new Exception(mes), mes));
+ exceptions.add(new MBeanRegistrationException(new Exception(mes), mes));
+ exceptions.add(new NotCompliantMBeanException());
+ exceptions.add(new OperationsException());
+ exceptions.add(new ReflectionException(new Exception(mes), mes));
+ exceptions.add(new RuntimeErrorException(new Error(mes), mes));
+ exceptions.add(new RuntimeMBeanException(new RuntimeException(mes), mes));
+ exceptions.add(new RuntimeOperationsException(new RuntimeException(mes), mes));
+ exceptions.add(new ServiceNotFoundException());
+ exceptions.add(new InvalidTargetObjectTypeException());
+ exceptions.add(new XMLParseException());
+ exceptions.add(new MonitorSettingException());
+ exceptions.add(new InvalidKeyException());
+ exceptions.add(new InvalidOpenTypeException());
+ exceptions.add(new KeyAlreadyExistsException());
+ exceptions.add(new OpenDataException());
+ exceptions.add(new InvalidRelationIdException());
+ exceptions.add(new InvalidRelationServiceException());
+ exceptions.add(new InvalidRelationTypeException());
+ exceptions.add(new InvalidRoleInfoException());
+ exceptions.add(new InvalidRoleValueException());
+ exceptions.add(new RelationException());
+ exceptions.add(new RelationNotFoundException());
+ exceptions.add(new RelationServiceNotRegisteredException());
+ exceptions.add(new RelationTypeNotFoundException());
+ exceptions.add(new RoleInfoNotFoundException());
+ exceptions.add(new RoleNotFoundException());
+ exceptions.add(new JMXProviderException());
+ exceptions.add(new JMXServerErrorException(mes, new Error(mes)));
+ ExceptionTest.Utils.debug(ExceptionTest.Utils.DEBUG_STANDARD,
+ "DataFactory::updateMap: Initialized" +
+ " an ArrayList with the " +
+ exceptions.size() + " exceptions of the JMX API");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/MBeanServer/ExceptionTest.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,372 @@
+/*
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8058865
+ * @summary Checks that exceptions are correctly wired (compared to reference).
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD ExceptionTest
+ */
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Properties;
+import java.lang.reflect.Method;
+
+import java.lang.management.ManagementFactory;
+import javax.management.ObjectName;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+
+public class ExceptionTest {
+
+ /*
+ * First Debug properties and arguments are collect in expected
+ * map (argName, value) format, then calls original test's run method.
+ */
+ public static void main(String args[]) throws Exception {
+
+ System.out.println("=================================================");
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+ Map<String, Object> map = Utils.parseParameters(args) ;
+
+ // Run test
+ ExceptionTest test = new ExceptionTest();
+ test.run(map);
+
+ }
+
+ public void run(Map<String, Object> args) {
+
+ System.out.println("ExceptionTest::run: Start");
+ int errorCount = 0;
+
+ JMXConnectorServer cs = null;
+ JMXConnector cc = null;
+
+ try {
+ // JMX MbeanServer used inside single VM as if remote.
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+ JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+ cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+ cs.start();
+
+ JMXServiceURL addr = cs.getAddress();
+ cc = JMXConnectorFactory.connect(addr);
+ MBeanServerConnection mbsc = cc.getMBeanServerConnection();
+
+ // ----
+ ObjectName objName =
+ new ObjectName(ExceptionThrower.EXCEPTION_THROWER_NAME);
+ System.out.println("ExceptionTest::run: Create and register MBean " + objName);
+ mbsc.createMBean("ExceptionThrower", objName);
+ System.out.println("---- OK\n");
+
+ // ----
+ System.out.println("ExceptionTest::run: Ask for exception(s)");
+ Object[] throwExceptionParam = new Object[1];
+ String[] throwExceptionSig = new String[]{"int"};
+
+ for (int i = 0; i < ExceptionFactory.exceptions.size(); i++) {
+ throwExceptionParam[0] = new Integer(i);
+
+ Exception ex =
+ (Exception)mbsc.invoke(objName,
+ "throwException", throwExceptionParam, throwExceptionSig);
+
+ if ( ! matches(ex, ExceptionFactory.exceptions.get(i)) ) {
+ errorCount++;
+ System.out.println("ExceptionTest::run: (ERROR) Received \n["
+ + ex + "]\nin place of\n["
+ + ExceptionFactory.exceptions.get(i) + "]");
+ } else {
+ System.out.println("OK [" + ex + "]");
+ }
+ }
+
+ System.out.println("---- DONE\n");
+
+ } catch (Exception e) {
+ Utils.printThrowable(e, true);
+ throw new RuntimeException();
+ } finally {
+ try {
+ // Close JMX Connector Client
+ cc.close();
+ // Stop connertor server
+ cs.stop();
+
+ } catch (Exception e) {
+ Utils.printThrowable(e, true);
+ throw new RuntimeException(
+ "Unable to either close connector client or stop connector server");
+ }
+ }
+
+ if (errorCount == 0) {
+ System.out.println("ExceptionTest::run: Done without any error");
+ } else {
+ System.out.println("ExceptionTest::run: Done with " + errorCount
+ + " error(s)");
+ throw new RuntimeException("errorCount = " + errorCount);
+ }
+
+ System.out.println("ExceptionTest::run: Done");
+ }
+
+ // Check both Exception are identical.
+ // That means:
+ // - none is null.
+ // - they are of the same Class.
+ // - if their respective messages aren't null they're equal.
+ // - if the message of one is null the message of the other is null too.
+ private boolean matches(Exception ex, Exception refex) {
+ if ( ex == null || refex == null ) {
+ System.out.println("(ERROR) Called with one or more null parameter; check "
+ + ex + " against " + refex);
+ return false;
+ }
+
+ String exClass = ex.getClass().getName();
+ String refexClass = refex.getClass().getName();
+
+ if ( ! exClass.equals(refexClass) ) {
+ System.out.println("(ERROR) Class names don't match; check ["
+ + exClass + "] against [" + refexClass + "]");
+ return false;
+ }
+
+ String exMes = ex.getMessage();
+ String refexMes = refex.getMessage();
+
+ if ( exMes != null && refexMes != null ) {
+ if ( ! exMes.equals(refexMes) ) {
+ System.out.println("(ERROR) Non null messages don't match; check ["
+ + exMes + "] against [" + refexMes + "]");
+ return false;
+ }
+ } else if ( (exMes == null && refexMes != null)
+ || (exMes != null && refexMes == null) ) {
+ System.out.println("(ERROR) Messages don't match; check [" + exMes
+ + "] against [" + refexMes + "]");
+ }
+
+ return true;
+ }
+
+ // Utility inner class coming from JMX Tonga test suite.
+ // Also used by ExceptionFactory.
+ static class Utils {
+
+ // DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property
+ static final String DEBUG_HEADER = "[debug] ";
+
+ // DEBUG levels
+ static int selectedDebugLevel = 0;
+ static final int DEBUG_STANDARD = 1;
+ static final int DEBUG_VERBOSE = 2; // Mainly used for stress tests
+ static final int DEBUG_ALL = DEBUG_STANDARD | DEBUG_VERBOSE;
+
+ static void parseDebugProperties() {
+ int level = 0;
+ Properties p = System.getProperties();
+
+ // get selected levels
+ if (p.getProperty("DEBUG_STANDARD") != null) {
+ level |= DEBUG_STANDARD;
+ }
+
+ if (p.getProperty("DEBUG_VERBOSE") != null) {
+ level |= DEBUG_VERBOSE;
+ }
+
+ if (p.getProperty("DEBUG_ALL") != null) {
+ level |= DEBUG_ALL;
+ }
+
+ selectedDebugLevel = level;
+ }
+
+ /**
+ * Reproduces the original parsing and collection of test parameters
+ * from the DTonga JMX test suite.
+ *
+ * Collects passed args and returns them in a map(argname, value) structure,
+ * which will be then propagated as necessary to various called methods.
+ */
+ static Map<String, Object> parseParameters(String args[])
+ throws Exception {
+ debug(DEBUG_STANDARD, "TestRoot::parseParameters: Start");
+ HashMap<String, Object> map = new HashMap<>();
+
+ for ( int i = 0; i < args.length; i++ ) {
+ if ( args[i].trim().startsWith("-") ) {
+ if ((i+1) < args.length && !args[i+1].startsWith("-") ) {
+ debug(DEBUG_STANDARD,
+ "TestRoot::parseParameters: added in map = " +
+ args[i] +
+ " with value " +
+ args[i+1]) ;
+ map.put(args[i].trim(), args[i+1].trim()) ;
+ } else if ((i+1) < args.length && args[i+1].startsWith("-") ||
+ (i+1) == args.length ) {
+ debug(DEBUG_STANDARD,
+ "TestRoot::parseParameters: added in map = " +
+ args[i] +
+ " with null value") ;
+ map.put(args[i].trim(), null) ;
+ } else {
+ System.out.println(
+ "TestRoot::parseParameters: (WARNING) not added in map = " +
+ args[i]) ;
+ }
+ }
+ }
+
+ debug(DEBUG_STANDARD, "TestRoot::parseParameters: Done") ;
+ return map ;
+ }
+
+ /**
+ * This method is to be used in all tests to print anything
+ * that is temporary.
+ * Printing is done only when debug is activated by the property DEBUG.
+ * Printing depends also on the DEBUG_LEVEL property.
+ * Here it encapsulates a System.out.println.
+ */
+ static void debug(int level, String line) {
+ if ((selectedDebugLevel & level) != 0) {
+ System.out.println(DEBUG_HEADER + line);
+ }
+ }
+
+ /**
+ * Do print stack trace when withStack is true.
+ * Does try to call getTargetException() and getTargetError() then
+ * print embedded stacks in the case of an Exception wrapping
+ * another Exception or an Error. Recurse until no more wrapping
+ * is found.
+ */
+ static void printThrowable(Throwable theThro, boolean withStack) {
+ try {
+ if (withStack) {
+ theThro.printStackTrace(System.out);
+ }
+ if (theThro instanceof Exception) {
+ Exception t = (Exception) theThro;
+ Method target = null;
+ String blank = " ";
+ try {
+ target = t.getClass().getMethod("getTargetException",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetException method could be there or not
+ }
+ System.out.println(blank + t.getClass() + "==>" + t.getMessage());
+ while (target != null) {
+ try {
+ t = (Exception) target.invoke(t,
+ (java.lang.Object[]) null);
+ } catch (Exception ee) {
+ t = null;
+ }
+ try {
+ if (t != null) {
+ blank = blank + " ";
+ System.out.println(blank + t.getClass() + "==>" +
+ t.getMessage());
+ try {
+ target =
+ t.getClass().getMethod("getTargetException",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetException method could be there or not }
+ }
+ } else {
+ target = null;
+ }
+ } catch (Exception ee) {
+ target = null;
+ }
+ }
+
+ // We may have exceptions wrapping an Error then it is
+ // getTargetError that is likely to be called
+ try {
+ target = ((Exception) theThro).getClass().getMethod("getTargetError",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetError method could be there or not
+ }
+ Throwable err = theThro;
+ while (target != null) {
+ try {
+ err = (Error) target.invoke(err,
+ (java.lang.Object[]) null);
+ } catch (Exception ee) {
+ err = null;
+ }
+ try {
+ if (err != null) {
+ blank = blank + " ";
+ System.out.println(blank + err.getClass() + "==>" +
+ err.getMessage());
+ if (withStack) {
+ err.printStackTrace(System.out);
+ }
+ try {
+ target = err.getClass().getMethod("getTargetError",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetError method could be there or not
+ }
+ } else {
+ target = null;
+ }
+ } catch (Exception ee) {
+ target = null;
+ }
+ }
+ } else {
+ System.out.println("Throwable is : " + theThro);
+ }
+ } catch (Throwable x) {
+ System.out.println("Exception : raised in printException : " + x);
+ }
+ }
+ }
+
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/MBeanServer/ExceptionThrower.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 class defines a simple standard MBean.
+ */
+public class ExceptionThrower implements ExceptionThrowerMBean {
+
+ public static final String EXCEPTION_THROWER_NAME
+ = "sqe:type=ExceptionThrower";
+
+ public Exception throwException(int exceptionIndex) {
+ return ExceptionFactory.exceptions.get(exceptionIndex);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/MBeanServer/ExceptionThrowerMBean.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 interface defines a simple standard MBean.
+ */
+public interface ExceptionThrowerMBean {
+ public Exception throwException(int exceptionIndex);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/mxbean/Basic.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,530 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import javax.management.Descriptor;
+import javax.management.ImmutableDescriptor;
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.Notification;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationEmitter;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+
+/**
+ * Class Basic
+ * Basic Description
+ */
+public class Basic implements BasicMXBean, NotificationEmitter,
+ MBeanRegistration {
+
+ public static final String EXCEPTION_MESSAGE = "from Basic";
+ public static final String NOTIFICATION_MESSAGE = "from Basic";
+ /** Attribute : IntAtt */
+ private int intAtt = 0;
+ /** Attribute : IntegerAtt */
+ private Integer integerAtt = 0;
+ /** Attribute : BoolAtt */
+ private boolean boolAtt = false;
+ /** Attribute : BooleanAtt */
+ private Boolean booleanAtt = false;
+ /** Attribute : StringAtt */
+ private String stringAtt = null;
+ /** Attribute : DateAtt */
+ private Date dateAtt = null;
+ /** Attribute : ObjectNameAtt */
+ private ObjectName objectNameAtt = null;
+ /** Attribute : NotifDescriptorAsMapAtt */
+ private Map<String, String> notifDescriptorAsMapAtt = null;
+ /** Attribute : NotifDescriptorAtt */
+ private Descriptor notifDescriptorAtt = null;
+ /** Attribute : SqeParameter */
+ private SqeParameter sqeParameterAtt = null;
+
+ /* Creates a new instance of Basic */
+ @SqeDescriptorKey("CONSTRUCTOR Basic")
+ public Basic() {
+ }
+
+ /* Creates a new instance of Basic */
+ @SqeDescriptorKey("CONSTRUCTOR Basic")
+ public Basic(
+ @SqeDescriptorKey("CONSTRUCTOR PARAMETER SqeParameter") SqeParameter param) {
+ }
+
+ /**
+ * Get int attribute
+ */
+ public int getIntAtt() {
+ return intAtt;
+ }
+
+ /**
+ * Set int attribute
+ */
+ public void setIntAtt(int value) {
+ intAtt = value;
+ }
+
+ /**
+ * Get Integer attribute
+ */
+ public Integer getIntegerAtt() {
+ return integerAtt;
+ }
+
+ /**
+ * Set Integer attribute
+ */
+ public void setIntegerAtt(Integer value) {
+ integerAtt = value;
+ }
+
+ /**
+ * Get boolean attribute
+ */
+ public boolean getBoolAtt() {
+ return boolAtt;
+ }
+
+ /**
+ * Set boolean attribute
+ */
+ public void setBoolAtt(boolean value) {
+ boolAtt = value;
+ }
+
+ /**
+ * Get Boolean attribute
+ */
+ public Boolean getBooleanAtt() {
+ return booleanAtt;
+ }
+
+ /**
+ * Set Boolean attribute
+ */
+ public void setBooleanAtt(Boolean value) {
+ booleanAtt = value;
+ }
+
+ /**
+ * Get String attribute
+ */
+ public String getStringAtt() {
+ return stringAtt;
+ }
+
+ /**
+ * Set String attribute
+ */
+ public void setStringAtt(String value) {
+ stringAtt = value;
+ }
+
+ /**
+ * Get Date attribute
+ */
+ public Date getDateAtt() {
+ return dateAtt;
+ }
+
+ /**
+ * Set Date attribute
+ */
+ public void setDateAtt(Date value) {
+ dateAtt = value;
+ }
+
+ /**
+ * Get ObjectName attribute
+ */
+ public ObjectName getObjectNameAtt() {
+ return objectNameAtt;
+ }
+
+ /**
+ * Set ObjectName attribute
+ */
+ public void setObjectNameAtt(ObjectName value) {
+ objectNameAtt = value;
+ }
+
+ /**
+ * Get SqeParameter attribute
+ */
+ public SqeParameter getSqeParameterAtt() throws Exception {
+ if (sqeParameterAtt == null) {
+ sqeParameterAtt = new SqeParameter();
+ sqeParameterAtt.setGlop("INITIALIZED");
+ }
+
+ return sqeParameterAtt;
+ }
+
+ /**
+ * Set SqeParameter attribute
+ */
+ public void setSqeParameterAtt(SqeParameter value) {
+ sqeParameterAtt = value;
+ }
+
+ /**
+ * Get the Descriptor used to build the NotificationInfo
+ * of emitted notifications.
+ */
+ public Map<String, String> getNotifDescriptorAsMapAtt() {
+ if (notifDescriptorAsMapAtt == null) {
+ initNotifDescriptorAtt();
+ }
+
+ return notifDescriptorAsMapAtt;
+ }
+
+ /**
+ * Set the Descriptor used to build the NotificationInfo
+ * of emitted notifications.
+ * <br>A Map<String, Object> would better fit Descriptor needs but then
+ * it is not convertible according the MXBean specification so the MBean
+ * registration fails.
+ * As we plan to test our custom Descriptor finds its way into
+ * the metadata of emitted notifications, String is good enough.
+ */
+ public void setNotifDescriptorAsMapAtt(Map<String, String> value) {
+ notifDescriptorAsMapAtt = new HashMap<String, String>(value);
+ notifDescriptorAtt = new ImmutableDescriptor(value);
+ }
+
+ /**
+ * Do nothing
+ */
+ public void doNothing() {
+ // I said NOTHING !
+ }
+
+ /**
+ * Do take SqeParameter as a parameter
+ */
+ public void doWeird(SqeParameter param) {
+ }
+
+ /**
+ * Throw an Exception
+ */
+ public void throwException() throws Exception {
+ throw new Exception(EXCEPTION_MESSAGE);
+ }
+
+ /**
+ * Throw an Error
+ */
+ public void throwError() {
+ throw new InternalError(EXCEPTION_MESSAGE);
+ }
+
+ /**
+ * Reset all attributes
+ */
+ public void reset() {
+ intAtt = 0;
+ integerAtt = 0;
+ boolAtt = false;
+ booleanAtt = Boolean.FALSE;
+ stringAtt = null;
+ dateAtt = null;
+ objectNameAtt = null;
+ }
+
+ /**
+ * Returns the weather for the coming days
+ * @param verbose <code>boolean</code> verbosity
+ * @throws java.lang.Exception <code>storm</code>
+ * @return <code>ObjectName</code>
+ */
+ public Weather getWeather(boolean verbose)
+ throws java.lang.Exception {
+ return Weather.SUNNY;
+ }
+
+ // Starting here are the 4 methods of MBeanRegistration interface.
+ // We use that to grab the ObjectName the MBean is registered with.
+ //
+ public ObjectName preRegister(MBeanServer server, ObjectName name)
+ throws Exception {
+ // Grab a reference on the MBeanServer we're registered in.
+ mbs = server;
+ // Compute the name we're registered with.
+ if (name != null) {
+ mbeanName = name;
+ return name;
+ } else {
+ mbeanName =
+ new ObjectName("sqe:type=" + Basic.class.getName());
+ return mbeanName;
+ }
+ }
+
+ public void postRegister(Boolean registrationDone) {
+ // Do nothing
+ }
+
+ public void preDeregister() throws Exception {
+ // Do nothing
+ }
+
+ public void postDeregister() {
+ // Do nothing
+ }
+
+ /**
+ * Send one Notification of the provided notifType type.
+ */
+ public void sendNotification(String notifType) {
+ Notification notification = null;
+
+ if (notifType.equals(NOTIF_TYPE_0)) {
+ notification = new Notification(NOTIF_TYPE_0,
+ mbeanName,
+ seqNumber,
+ NOTIFICATION_MESSAGE);
+ } else if (notifType.equals(NOTIF_TYPE_1)) {
+ notification = new SqeNotification(NOTIF_TYPE_1,
+ mbeanName,
+ seqNumber,
+ NOTIFICATION_MESSAGE);
+ }
+
+ seqNumber++;
+ broadcaster.sendNotification(notification);
+ }
+
+ /**
+ * That method starts a set of threads, each thread sends a given number of
+ * notifications.
+ * The number of threads can be set via the attribute numOfNotificationSenders.
+ * The number of notification sent by each thread can be set via
+ * the attribute numOfNotificationSenderLoops.
+ * Depending on the parameter customNotification we send either custom
+ * notification(s) or MBeanServer registration and unregistration notification(s).
+ * When customNotification=true the total number of notification(s) sent is
+ * (numOfNotificationSenders * numOfNotificationSenderLoops). They are
+ * sequentially of type NOTIF_TYPE_0 then NOTIF_TYPE_1 and so on.
+ *
+ * When customNotification=false the total number of notification(s) sent is
+ * (numOfNotificationSenders * numOfNotificationSenderLoops) registration
+ * notification(s)
+ * +
+ * (numOfNotificationSenders * numOfNotificationSenderLoops) unregistration
+ * notification(s)
+ *
+ * @throws java.lang.Exception
+ */
+ public void sendNotificationWave(boolean customNotification) throws
+ Exception {
+ // Build the set of notification sender.
+ Collection<Callable<Integer>> tasks =
+ new HashSet<Callable<Integer>>(numOfNotificationSenders);
+
+ for (int i = 1; i <= numOfNotificationSenders; i++) {
+ tasks.add(new NotifSender(numOfNotificationSenderLoops,
+ customNotification, i));
+ }
+
+ // Start all notification sender in parallel.
+ ExecutorService execServ = null;
+ try {
+ execServ = Executors.newFixedThreadPool(numOfNotificationSenders);
+ List<Future<Integer>> taskHandlers = execServ.invokeAll(tasks);
+ checkNotifSenderThreadStatus(taskHandlers);
+ } finally {
+ if (!execServ.isShutdown()) {
+ execServ.shutdown();
+ }
+ }
+ }
+
+ public void setNumOfNotificationSenders(int value) {
+ numOfNotificationSenders = value;
+ }
+
+ public void setNumOfNotificationSenderLoops(int value) {
+ numOfNotificationSenderLoops = value;
+ }
+
+ /**
+ * MBean Notification support
+ * You shouldn't update these methods
+ */
+ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">
+ public void addNotificationListener(NotificationListener listener,
+ NotificationFilter filter,
+ Object handback)
+ throws IllegalArgumentException {
+ broadcaster.addNotificationListener(listener, filter, handback);
+ }
+
+ public MBeanNotificationInfo[] getNotificationInfo() {
+ if (notifDescriptorAtt == null) {
+ initNotifDescriptorAtt();
+ }
+
+ return new MBeanNotificationInfo[]{
+ new MBeanNotificationInfo(new String[]{
+ NOTIF_TYPE_0
+ },
+ javax.management.Notification.class.getName(),
+ "Standard JMX Notification",
+ notifDescriptorAtt),
+ new MBeanNotificationInfo(new String[]{
+ NOTIF_TYPE_1
+ },
+ SqeNotification.class.getName(),
+ "SQE Notification",
+ notifDescriptorAtt)
+ };
+ }
+
+ public void removeNotificationListener(NotificationListener listener)
+ throws ListenerNotFoundException {
+ broadcaster.removeNotificationListener(listener);
+ }
+
+ public void removeNotificationListener(NotificationListener listener,
+ NotificationFilter filter,
+ Object handback)
+ throws ListenerNotFoundException {
+ broadcaster.removeNotificationListener(listener, filter, handback);
+ }
+ // </editor-fold>
+ private synchronized long getNextSeqNumber() {
+ return seqNumber++;
+ }
+
+ private void initNotifDescriptorAtt() {
+ String key = "CRABE";
+ String value = "TAMBOUR";
+ notifDescriptorAtt =
+ new ImmutableDescriptor(new String[]{key + "=" + value});
+ notifDescriptorAsMapAtt =
+ new HashMap<String, String>();
+ notifDescriptorAsMapAtt.put(key, value);
+ }
+
+ private void checkNotifSenderThreadStatus(
+ List<Future<Integer>> taskHandlers)
+ throws Exception {
+ String msgTag = "Basic::checkNotifSenderThreadStatus: ";
+ // Grab back status of each notification sender.
+ for (Future<Integer> f : taskHandlers) {
+ if (f.isCancelled()) {
+ String message = msgTag +
+ "---- ERROR : One thread has been cancelled";
+ System.out.println(message);
+ throw new RuntimeException(message);
+ } else {
+ Integer effectiveNumOfLoops = f.get();
+
+ if (effectiveNumOfLoops != numOfNotificationSenderLoops) {
+ String message = msgTag + "---- ERROR : One thread did " +
+ effectiveNumOfLoops + " loops in place of " +
+ numOfNotificationSenderLoops;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ }
+ }
+ }
+ //
+ private int numOfNotificationSenderLoops = 2;
+ private int numOfNotificationSenders = 13;
+
+ private class NotifSender implements Callable<Integer> {
+
+ private int cycles;
+ private boolean customNotification;
+ private int senderID;
+
+ public NotifSender(int cycles, boolean customNotification, int id) {
+ this.cycles = cycles;
+ this.customNotification = customNotification;
+ this.senderID = id;
+ }
+
+ public Integer call() throws Exception {
+ int callsDone = 0;
+
+ try {
+ for (int i = 1; i <= cycles; i++) {
+ if (customNotification) {
+ if (i % 2 == 0) {
+ sendNotification(NOTIF_TYPE_0);
+ } else {
+ sendNotification(NOTIF_TYPE_1);
+ }
+ } else {
+ ObjectName mbeanName = new ObjectName("SQE:type=" +
+ mbeanClassName + ",senderID=" + senderID);
+ mbs.createMBean(mbeanClassName, mbeanName);
+ mbs.unregisterMBean(mbeanName);
+ }
+ callsDone++;
+ }
+ } catch (Exception e) {
+ System.out.println("NotifSender::call: (ERROR) Thread [" + senderID +
+ "] failed after " + callsDone + " cycles");
+ throw e;
+ }
+
+ return Integer.valueOf(callsDone);
+ }
+ }
+
+ //
+ private long seqNumber;
+ private final NotificationBroadcasterSupport broadcaster =
+ new NotificationBroadcasterSupport();
+ private ObjectName mbeanName;
+ private MBeanServer mbs;
+ private String mbeanClassName = "Simple";
+
+ /**
+ * Notification types definitions. To use when creating JMX Notifications.
+ */
+ public static final String NOTIF_TYPE_0 =
+ "sqe.notification.a.type";
+ public static final String NOTIF_TYPE_1 =
+ "sqe.notification.b.type";
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/mxbean/BasicMXBean.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Date;
+import java.util.Map;
+
+import javax.management.ObjectName;
+
+/**
+ * Interface BasicMBean
+ * Basic Description
+ */
+@SqeDescriptorKey("INTERFACE BasicMXBean")
+public interface BasicMXBean
+{
+ /**
+ * Get int attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE intAtt")
+ public int getIntAtt();
+
+ /**
+ * Set int attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE intAtt")
+ public void setIntAtt(int value);
+
+ /**
+ * Get Integer attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE integerAtt")
+ public Integer getIntegerAtt();
+
+ /**
+ * Set Integer attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE integerAtt")
+ public void setIntegerAtt(Integer value);
+
+ /**
+ * Get boolean attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE boolAtt")
+ public boolean getBoolAtt();
+
+ /**
+ * Set boolean attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE boolAtt")
+ public void setBoolAtt(boolean value);
+
+ /**
+ * Get Boolean attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE booleanAtt")
+ public Boolean getBooleanAtt();
+
+ /**
+ * Set Boolean attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE booleanAtt")
+ public void setBooleanAtt(Boolean value);
+
+ /**
+ * Get String attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE stringAtt")
+ public String getStringAtt();
+
+ /**
+ * Set String attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE stringAtt")
+ public void setStringAtt(String value);
+
+ /**
+ * Get Date attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE dateAtt")
+ public Date getDateAtt();
+
+ /**
+ * Set Date attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE dateAtt")
+ public void setDateAtt(Date value);
+
+ /**
+ * Get ObjectName attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE objectNameAtt")
+ public ObjectName getObjectNameAtt();
+
+ /**
+ * Set ObjectName attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE objectNameAtt")
+ public void setObjectNameAtt(ObjectName value);
+
+ /**
+ * Get SqeParameter attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE sqeParameterAtt")
+ public SqeParameter getSqeParameterAtt() throws Exception;
+
+ /**
+ * Set SqeParameter attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE sqeParameterAtt")
+ public void setSqeParameterAtt(SqeParameter value);
+
+ /**
+ * Set NumOfNotificationSenders attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE NumOfNotificationSenders")
+ public void setNumOfNotificationSenders(int value);
+
+ /**
+ * Set NumOfNotificationSenderLoops attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE NumOfNotificationSenderLoops")
+ public void setNumOfNotificationSenderLoops(int value);
+
+ /**
+ * do nothing
+ *
+ */
+ @SqeDescriptorKey("OPERATION doNothing")
+ public void doNothing();
+
+ /**
+ * Do take SqeParameter as a parameter
+ */
+ @SqeDescriptorKey("OPERATION doWeird")
+ public void doWeird(@SqeDescriptorKey("METHOD PARAMETER")SqeParameter param);
+
+ /**
+ * throw an Exception
+ *
+ */
+ @SqeDescriptorKey("OPERATION throwException")
+ public void throwException() throws Exception;
+
+ /**
+ * throw an Error
+ *
+ */
+ @SqeDescriptorKey("OPERATION throwError")
+ public void throwError();
+
+ /**
+ * reset all attributes
+ *
+ */
+ @SqeDescriptorKey("OPERATION reset")
+ public void reset();
+
+ /**
+ * returns the weather for the coming days
+ *
+ * @param verbose <code>boolean</code> verbosity
+ * @return <code>ObjectName</code>
+ */
+ @SqeDescriptorKey("OPERATION getWeather")
+ public Weather getWeather(@SqeDescriptorKey("METHOD PARAMETER")boolean verbose)
+ throws java.lang.Exception;
+
+ public enum Weather {
+ CLOUDY, SUNNY
+ }
+
+ @SqeDescriptorKey("ATTRIBUTE notifDescriptorAsMapAtt")
+ public Map<String, String> getNotifDescriptorAsMapAtt();
+
+ @SqeDescriptorKey("ATTRIBUTE notifDescriptorAsMapAtt")
+ public void setNotifDescriptorAsMapAtt(Map<String, String> value);
+
+ @SqeDescriptorKey("OPERATION sendNotification")
+ public void sendNotification(@SqeDescriptorKey("METHOD PARAMETER")String notifType);
+
+ @SqeDescriptorKey("OPERATION sendNotificationWave")
+ public void sendNotificationWave(boolean customNotification) throws Exception;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/mxbean/MXBeanExceptionHandlingTest.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8058865
+ * @summary Checks correct exception and error events from NotificationListener
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @compile Basic.java
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanExceptionHandlingTest -timeForNotificationInSeconds 3
+ */
+
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+
+import java.lang.management.ManagementFactory;
+import javax.management.MBeanServer;
+import javax.management.MBeanException;
+import javax.management.MBeanServerDelegate;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.RuntimeErrorException;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+public class MXBeanExceptionHandlingTest implements NotificationListener {
+
+ private static String BASIC_MXBEAN_CLASS_NAME = "Basic";
+
+ private long timeForNotificationInSeconds = 3L;
+ private int numOfNotifications = 2;
+ private BlockingQueue<Notification> notifList = null;
+
+
+ /*
+ * First Debug properties and arguments are collect in expected
+ * map (argName, value) format, then calls original test's run method.
+ */
+ public static void main(String args[]) throws Exception {
+
+ System.out.println("=================================================");
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+ Map<String, Object> map = Utils.parseParameters(args) ;
+
+ // Run test
+ MXBeanExceptionHandlingTest test = new MXBeanExceptionHandlingTest();
+ test.run(map);
+
+ }
+
+ protected void parseArgs(Map<String, Object> args) throws Exception {
+
+ String arg = null;
+
+ // Init timeForNotificationInSeconds
+ // It is the maximum time in seconds we wait for a notification.
+ arg = (String)args.get("-timeForNotificationInSeconds") ;
+ if (arg != null) {
+ timeForNotificationInSeconds = (new Long(arg)).longValue();
+ }
+
+ }
+
+ public void run(Map<String, Object> args) {
+
+ System.out.println("MXBeanExceptionHandlingTest::run: Start") ;
+ int errorCount = 0 ;
+
+ try {
+ parseArgs(args);
+ notifList = new ArrayBlockingQueue<Notification>(numOfNotifications);
+
+ // JMX MbeanServer used inside single VM as if remote.
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+ JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+ JMXConnectorServer cs =
+ JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+ cs.start();
+
+ JMXServiceURL addr = cs.getAddress();
+ JMXConnector cc = JMXConnectorFactory.connect(addr);
+ MBeanServerConnection mbsc = cc.getMBeanServerConnection();
+
+ // ----
+ System.out.println("Add me as notification listener");
+ mbsc.addNotificationListener(MBeanServerDelegate.DELEGATE_NAME,
+ this, null, null);
+ System.out.println("---- OK\n") ;
+
+ // ----
+ System.out.println("Create and register the MBean");
+ ObjectName objName = new ObjectName("sqe:type=Basic,protocol=rmi") ;
+ mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName);
+ System.out.println("---- OK\n") ;
+
+ // ----
+ System.out.println("Call method throwException on our MXBean");
+
+ try {
+ mbsc.invoke(objName, "throwException", null, null);
+ errorCount++;
+ System.out.println("(ERROR) Did not get awaited MBeanException") ;
+ } catch (MBeanException mbe) {
+ System.out.println("(OK) Got awaited MBeanException") ;
+ Throwable cause = mbe.getCause();
+
+ if ( cause instanceof java.lang.Exception ) {
+ System.out.println("(OK) Cause is of the right class") ;
+ String mess = cause.getMessage();
+
+ if ( mess.equals(Basic.EXCEPTION_MESSAGE ) ) {
+ System.out.println("(OK) Cause message is fine") ;
+ } else {
+ errorCount++;
+ System.out.println("(ERROR) Cause has message "
+ + cause.getMessage()
+ + " as we expect "
+ + Basic.EXCEPTION_MESSAGE) ;
+ }
+ } else {
+ errorCount++;
+ System.out.println("(ERROR) Cause is of class "
+ + cause.getClass().getName()
+ + " as we expect java.lang.Exception") ;
+ }
+ } catch (Exception e) {
+ errorCount++;
+ System.out.println("(ERROR) Did not get awaited MBeanException but "
+ + e) ;
+ Utils.printThrowable(e, true);
+ }
+ System.out.println("---- DONE\n") ;
+
+ // ----
+ System.out.println("Call method throwError on our MXBean");
+
+ try {
+ mbsc.invoke(objName, "throwError", null, null);
+ errorCount++;
+ System.out.println("(ERROR) Did not get awaited RuntimeErrorException") ;
+ } catch (RuntimeErrorException ree) {
+ System.out.println("(OK) Got awaited RuntimeErrorException") ;
+ Throwable cause = ree.getCause();
+
+ if ( cause instanceof java.lang.InternalError ) {
+ System.out.println("(OK) Cause is of the right class") ;
+ String mess = cause.getMessage();
+
+ if ( mess.equals(Basic.EXCEPTION_MESSAGE ) ) {
+ System.out.println("(OK) Cause message is fine") ;
+ } else {
+ errorCount++;
+ System.out.println("(ERROR) Cause has message "
+ + cause.getMessage()
+ + " as we expect "
+ + Basic.EXCEPTION_MESSAGE) ;
+ }
+ } else {
+ errorCount++;
+ System.out.println("(ERROR) Cause is of class "
+ + cause.getClass().getName()
+ + " as we expect java.lang.InternalError") ;
+ }
+ } catch (Exception e) {
+ errorCount++;
+ System.out.println("(ERROR) Did not get awaited RuntimeErrorException but "
+ + e) ;
+ Utils.printThrowable(e, true);
+ }
+ System.out.println("---- DONE\n") ;
+
+ // ----
+ System.out.println("Unregister the MBean");
+ mbsc.unregisterMBean(objName);
+ System.out.println("---- OK\n") ;
+
+ Thread.sleep(timeForNotificationInSeconds * 1000);
+ int numOfReceivedNotif = notifList.size();
+
+ if ( numOfReceivedNotif == numOfNotifications ) {
+ System.out.println("(OK) We received "
+ + numOfNotifications
+ + " Notifications") ;
+ } else {
+ errorCount++;
+ System.out.println("(ERROR) We received "
+ + numOfReceivedNotif
+ + " Notifications in place of "
+ + numOfNotifications) ;
+ }
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ throw new RuntimeException(e);
+ }
+
+ if ( errorCount == 0 ) {
+ System.out.println("MXBeanExceptionHandlingTest::run: Done without any error") ;
+ } else {
+ System.out.println("MXBeanExceptionHandlingTest::run: Done with "
+ + errorCount
+ + " error(s)") ;
+ throw new RuntimeException("errorCount = " + errorCount);
+ }
+ }
+
+ public void handleNotification(Notification notification, Object handback) {
+ System.out.println("MXBeanExceptionHandlingTest::handleNotification: Received "
+ + notification);
+ notifList.add(notification);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/mxbean/MXBeanInteropTest1.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,638 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8058865
+ * @summary Test all MXBeans available by default on the platform
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanInteropTest1
+ */
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import java.lang.management.ClassLoadingMXBean;
+import java.lang.management.CompilationMXBean;
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+import java.lang.management.MemoryManagerMXBean;
+import java.lang.management.MemoryPoolMXBean;
+import java.lang.management.OperatingSystemMXBean;
+import java.lang.management.RuntimeMXBean;
+import java.lang.management.ThreadMXBean;
+
+import javax.management.JMX;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanConstructorInfo;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+public class MXBeanInteropTest1 {
+
+ /*
+ * First Debug properties and arguments are collect in expected
+ * map (argName, value) format, then calls original test's run method.
+ */
+ public static void main(String args[]) throws Exception {
+
+ System.out.println("=================================================");
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+ Map<String, Object> map = Utils.parseParameters(args) ;
+
+ // Run test
+ MXBeanInteropTest1 test = new MXBeanInteropTest1();
+ test.run(map);
+
+ }
+
+ public void run(Map<String, Object> args) {
+
+ System.out.println("MXBeanInteropTest1::run: Start") ;
+ int errorCount = 0 ;
+
+ try {
+ // JMX MbeanServer used inside single VM as if remote.
+ // MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+ JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+ JMXConnectorServer cs =
+ JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+ cs.start();
+
+ JMXServiceURL addr = cs.getAddress();
+ JMXConnector cc = JMXConnectorFactory.connect(addr);
+ MBeanServerConnection mbsc = cc.getMBeanServerConnection();
+
+ // Print out registered java.lang.management MXBeans found
+ // in the remote jvm.
+ printMBeans(mbsc) ;
+
+ // For each possible kind of JDK 5 defined MXBean, we retrieve its
+ // MBeanInfo and print it and we call all getters and print
+ // their output.
+ errorCount += doClassLoadingMXBeanTest(mbsc) ;
+ errorCount += doMemoryMXBeanTest(mbsc) ;
+ errorCount += doThreadMXBeanTest(mbsc) ;
+ errorCount += doRuntimeMXBeanTest(mbsc) ;
+ errorCount += doOperatingSystemMXBeanTest(mbsc) ;
+ errorCount += doCompilationMXBeanTest(mbsc) ;
+ errorCount += doGarbageCollectorMXBeanTest(mbsc) ;
+ errorCount += doMemoryManagerMXBeanTest(mbsc) ;
+ errorCount += doMemoryPoolMXBeanTest(mbsc) ;
+
+ // Terminate the JMX Client
+ cc.close();
+
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ throw new RuntimeException(e);
+ }
+
+ if ( errorCount == 0 ) {
+ System.out.println("MXBeanInteropTest1::run: Done without any error") ;
+ } else {
+ System.out.println("MXBeanInteropTest1::run: Done with "
+ + errorCount
+ + " error(s)") ;
+ throw new RuntimeException("errorCount = " + errorCount);
+ }
+ }
+
+ /**
+ * Prints all MBeans of domain java.lang.
+ * They are MBeans related to the JSR 174 that defines
+ * package java.lang.management.
+ */
+ private static void printMBeans(MBeanServerConnection mbsc) throws Exception {
+ ObjectName filterName = new ObjectName("java.lang:*");
+ Set<ObjectName> set = mbsc.queryNames(filterName, null);
+
+ if ( set.size() == 0 ) {
+ throw new RuntimeException("(ERROR) No MBean found with filter "
+ + filterName);
+ }
+
+ System.out.println("---- MBeans found in domain java.lang :");
+
+ for (Iterator<ObjectName> iter = set.iterator(); iter.hasNext(); ) {
+ System.out.println(iter.next().toString());
+ }
+
+ System.out.println("\n") ;
+ }
+
+
+ private final int doClassLoadingMXBeanTest(MBeanServerConnection mbsc) {
+ int errorCount = 0 ;
+ System.out.println("---- ClassLoadingMXBean") ;
+
+ try {
+ ObjectName classLoadingName =
+ new ObjectName(ManagementFactory.CLASS_LOADING_MXBEAN_NAME) ;
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(classLoadingName);
+ errorCount += checkNonEmpty(mbInfo);
+ System.out.println("getMBeanInfo\t\t"
+ + mbInfo);
+ ClassLoadingMXBean classLoading = null;
+
+ classLoading = JMX.newMXBeanProxy(mbsc,
+ classLoadingName,
+ ClassLoadingMXBean.class) ;
+ System.out.println("getLoadedClassCount\t\t"
+ + classLoading.getLoadedClassCount());
+ System.out.println("getTotalLoadedClassCount\t\t"
+ + classLoading.getTotalLoadedClassCount());
+ System.out.println("getUnloadedClassCount\t\t"
+ + classLoading.getUnloadedClassCount());
+ System.out.println("isVerbose\t\t"
+ + classLoading.isVerbose());
+
+ System.out.println("---- OK\n") ;
+
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++ ;
+ System.out.println("---- ERROR\n") ;
+ }
+
+ return errorCount ;
+ }
+
+
+ private final int doMemoryMXBeanTest(MBeanServerConnection mbsc) {
+ int errorCount = 0 ;
+ System.out.println("---- MemoryMXBean") ;
+
+ try {
+ ObjectName memoryName =
+ new ObjectName(ManagementFactory.MEMORY_MXBEAN_NAME) ;
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(memoryName);
+ errorCount += checkNonEmpty(mbInfo);
+ System.out.println("getMBeanInfo\t\t"
+ + mbInfo);
+ MemoryMXBean memory = null ;
+
+ memory =
+ JMX.newMXBeanProxy(mbsc,
+ memoryName,
+ MemoryMXBean.class,
+ true) ;
+ System.out.println("getMemoryHeapUsage\t\t"
+ + memory.getHeapMemoryUsage());
+ System.out.println("getNonHeapMemoryHeapUsage\t\t"
+ + memory.getNonHeapMemoryUsage());
+ System.out.println("getObjectPendingFinalizationCount\t\t"
+ + memory.getObjectPendingFinalizationCount());
+ System.out.println("isVerbose\t\t"
+ + memory.isVerbose());
+
+ System.out.println("---- OK\n") ;
+
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++ ;
+ System.out.println("---- ERROR\n") ;
+ }
+
+ return errorCount ;
+ }
+
+
+ private final int doThreadMXBeanTest(MBeanServerConnection mbsc) {
+ int errorCount = 0 ;
+ System.out.println("---- ThreadMXBean") ;
+
+ try {
+ ObjectName threadName =
+ new ObjectName(ManagementFactory.THREAD_MXBEAN_NAME) ;
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(threadName);
+ errorCount += checkNonEmpty(mbInfo);
+ System.out.println("getMBeanInfo\t\t" + mbInfo);
+ ThreadMXBean thread = null ;
+
+ thread =
+ JMX.newMXBeanProxy(mbsc,
+ threadName,
+ ThreadMXBean.class) ;
+ System.out.println("findMonitorDeadlockedThreads\t\t"
+ + thread.findMonitorDeadlockedThreads());
+ long[] threadIDs = thread.getAllThreadIds() ;
+ System.out.println("getAllThreadIds\t\t"
+ + threadIDs);
+
+ for ( long threadID : threadIDs ) {
+ System.out.println("getThreadInfo long\t\t"
+ + thread.getThreadInfo(threadID));
+ System.out.println("getThreadInfo long, int\t\t"
+ + thread.getThreadInfo(threadID, 2));
+ }
+
+ System.out.println("getThreadInfo long[]\t\t"
+ + thread.getThreadInfo(threadIDs));
+ System.out.println("getThreadInfo long[], int\t\t"
+ + thread.getThreadInfo(threadIDs, 2));
+ System.out.println("getDaemonThreadCount\t\t"
+ + thread.getDaemonThreadCount());
+ System.out.println("getPeakThreadCount\t\t"
+ + thread.getPeakThreadCount());
+ System.out.println("getThreadCount\t\t"
+ + thread.getThreadCount());
+ System.out.println("getTotalStartedThreadCount\t\t"
+ + thread.getTotalStartedThreadCount());
+ boolean supported = thread.isThreadContentionMonitoringSupported() ;
+ System.out.println("isThreadContentionMonitoringSupported\t\t"
+ + supported);
+
+ if ( supported ) {
+ System.out.println("isThreadContentionMonitoringEnabled\t\t"
+ + thread.isThreadContentionMonitoringEnabled());
+ }
+
+ supported = thread.isThreadCpuTimeSupported() ;
+ System.out.println("isThreadCpuTimeSupported\t\t"
+ + supported);
+
+ if ( supported ) {
+ System.out.println("isThreadCpuTimeEnabled\t\t"
+ + thread.isThreadCpuTimeEnabled());
+
+ for (long id : threadIDs) {
+ System.out.println("getThreadCpuTime(" + id + ")\t\t"
+ + thread.getThreadCpuTime(id));
+ System.out.println("getThreadUserTime(" + id + ")\t\t"
+ + thread.getThreadUserTime(id));
+ }
+ }
+
+ supported = thread.isCurrentThreadCpuTimeSupported() ;
+ System.out.println("isCurrentThreadCpuTimeSupported\t\t"
+ + supported);
+
+ if ( supported ) {
+ System.out.println("getCurrentThreadCpuTime\t\t"
+ + thread.getCurrentThreadCpuTime());
+ System.out.println("getCurrentThreadUserTime\t\t"
+ + thread.getCurrentThreadUserTime());
+ }
+
+ thread.resetPeakThreadCount() ;
+
+ System.out.println("---- OK\n") ;
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++ ;
+ System.out.println("---- ERROR\n") ;
+ }
+
+ return errorCount ;
+ }
+
+
+ private final int doRuntimeMXBeanTest(MBeanServerConnection mbsc) {
+ int errorCount = 0 ;
+ System.out.println("---- RuntimeMXBean") ;
+
+ try {
+ ObjectName runtimeName =
+ new ObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME) ;
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(runtimeName);
+ errorCount += checkNonEmpty(mbInfo);
+ System.out.println("getMBeanInfo\t\t" + mbInfo);
+ RuntimeMXBean runtime = null;
+
+ runtime =
+ JMX.newMXBeanProxy(mbsc,
+ runtimeName,
+ RuntimeMXBean.class) ;
+ System.out.println("getClassPath\t\t"
+ + runtime.getClassPath());
+ System.out.println("getInputArguments\t\t"
+ + runtime.getInputArguments());
+ System.out.println("getLibraryPath\t\t"
+ + runtime.getLibraryPath());
+ System.out.println("getManagementSpecVersion\t\t"
+ + runtime.getManagementSpecVersion());
+ System.out.println("getName\t\t"
+ + runtime.getName());
+ System.out.println("getSpecName\t\t"
+ + runtime.getSpecName());
+ System.out.println("getSpecVendor\t\t"
+ + runtime.getSpecVendor());
+ System.out.println("getSpecVersion\t\t"
+ + runtime.getSpecVersion());
+ System.out.println("getStartTime\t\t"
+ + runtime.getStartTime());
+ System.out.println("getSystemProperties\t\t"
+ + runtime.getSystemProperties());
+ System.out.println("getUptime\t\t"
+ + runtime.getUptime());
+ System.out.println("getVmName\t\t"
+ + runtime.getVmName());
+ System.out.println("getVmVendor\t\t"
+ + runtime.getVmVendor());
+ System.out.println("getVmVersion\t\t"
+ + runtime.getVmVersion());
+ boolean supported = runtime.isBootClassPathSupported() ;
+ System.out.println("isBootClassPathSupported\t\t"
+ + supported);
+
+ if ( supported ) {
+ System.out.println("getBootClassPath\t\t"
+ + runtime.getBootClassPath());
+ }
+
+ System.out.println("---- OK\n") ;
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++ ;
+ System.out.println("---- ERROR\n") ;
+ }
+
+ return errorCount ;
+ }
+
+
+ private final int doOperatingSystemMXBeanTest(MBeanServerConnection mbsc) {
+ int errorCount = 0 ;
+ System.out.println("---- OperatingSystemMXBean") ;
+
+ try {
+ ObjectName operationName =
+ new ObjectName(ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME) ;
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(operationName);
+ errorCount += checkNonEmpty(mbInfo);
+ System.out.println("getMBeanInfo\t\t" + mbInfo);
+ OperatingSystemMXBean operation = null ;
+
+ operation =
+ JMX.newMXBeanProxy(mbsc,
+ operationName,
+ OperatingSystemMXBean.class) ;
+ System.out.println("getArch\t\t"
+ + operation.getArch());
+ System.out.println("getAvailableProcessors\t\t"
+ + operation.getAvailableProcessors());
+ System.out.println("getName\t\t"
+ + operation.getName());
+ System.out.println("getVersion\t\t"
+ + operation.getVersion());
+
+ System.out.println("---- OK\n") ;
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++ ;
+ System.out.println("---- ERROR\n") ;
+ }
+
+ return errorCount ;
+ }
+
+
+ private final int doCompilationMXBeanTest(MBeanServerConnection mbsc) {
+ int errorCount = 0 ;
+ System.out.println("---- CompilationMXBean") ;
+
+ try {
+ ObjectName compilationName =
+ new ObjectName(ManagementFactory.COMPILATION_MXBEAN_NAME);
+
+ if ( mbsc.isRegistered(compilationName) ) {
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(compilationName);
+ errorCount += checkNonEmpty(mbInfo);
+ System.out.println("getMBeanInfo\t\t" + mbInfo);
+ CompilationMXBean compilation = null ;
+
+ compilation =
+ JMX.newMXBeanProxy(mbsc,
+ compilationName,
+ CompilationMXBean.class) ;
+ System.out.println("getName\t\t"
+ + compilation.getName());
+ boolean supported =
+ compilation.isCompilationTimeMonitoringSupported() ;
+ System.out.println("isCompilationTimeMonitoringSupported\t\t"
+ + supported);
+
+ if ( supported ) {
+ System.out.println("getTotalCompilationTime\t\t"
+ + compilation.getTotalCompilationTime());
+ }
+ }
+
+ System.out.println("---- OK\n") ;
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++ ;
+ System.out.println("---- ERROR\n") ;
+ }
+
+ return errorCount ;
+ }
+
+
+ private final int doGarbageCollectorMXBeanTest(MBeanServerConnection mbsc) {
+ int errorCount = 0 ;
+ System.out.println("---- GarbageCollectorMXBean") ;
+
+ try {
+ ObjectName filterName =
+ new ObjectName(ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE
+ + ",*");
+ Set<ObjectName> onSet = mbsc.queryNames(filterName, null);
+
+ for (Iterator<ObjectName> iter = onSet.iterator(); iter.hasNext(); ) {
+ ObjectName garbageName = iter.next() ;
+ System.out.println("-------- " + garbageName) ;
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(garbageName);
+ errorCount += checkNonEmpty(mbInfo);
+ System.out.println("getMBeanInfo\t\t" + mbInfo);
+ GarbageCollectorMXBean garbage = null ;
+
+ garbage =
+ JMX.newMXBeanProxy(mbsc,
+ garbageName,
+ GarbageCollectorMXBean.class) ;
+ System.out.println("getCollectionCount\t\t"
+ + garbage.getCollectionCount());
+ System.out.println("getCollectionTime\t\t"
+ + garbage.getCollectionTime());
+ }
+
+ System.out.println("---- OK\n") ;
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++ ;
+ System.out.println("---- ERROR\n") ;
+ }
+
+ return errorCount ;
+ }
+
+
+ private final int doMemoryManagerMXBeanTest(MBeanServerConnection mbsc) {
+ int errorCount = 0 ;
+ System.out.println("---- MemoryManagerMXBean") ;
+
+ try {
+ ObjectName filterName =
+ new ObjectName(ManagementFactory.MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE
+ + ",*");
+ Set<ObjectName> onSet = mbsc.queryNames(filterName, null);
+
+ for (Iterator<ObjectName> iter = onSet.iterator(); iter.hasNext(); ) {
+ ObjectName memoryManagerName = iter.next() ;
+ System.out.println("-------- " + memoryManagerName) ;
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(memoryManagerName);
+ System.out.println("getMBeanInfo\t\t" + mbInfo);
+ errorCount += checkNonEmpty(mbInfo);
+ MemoryManagerMXBean memoryManager = null;
+
+ memoryManager =
+ JMX.newMXBeanProxy(mbsc,
+ memoryManagerName,
+ MemoryManagerMXBean.class) ;
+ System.out.println("getMemoryPoolNames\t\t"
+ + Arrays.deepToString(memoryManager.getMemoryPoolNames()));
+ System.out.println("getName\t\t"
+ + memoryManager.getName());
+ System.out.println("isValid\t\t"
+ + memoryManager.isValid());
+ }
+
+ System.out.println("---- OK\n") ;
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++ ;
+ System.out.println("---- ERROR\n") ;
+ }
+
+ return errorCount ;
+ }
+
+
+ private final int doMemoryPoolMXBeanTest(MBeanServerConnection mbsc) {
+ int errorCount = 0 ;
+ System.out.println("---- MemoryPoolMXBean") ;
+
+ try {
+ ObjectName filterName =
+ new ObjectName(ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE
+ + ",*");
+ Set<ObjectName> onSet = mbsc.queryNames(filterName, null);
+
+ for (Iterator<ObjectName> iter = onSet.iterator(); iter.hasNext(); ) {
+ ObjectName memoryPoolName = iter.next() ;
+ System.out.println("-------- " + memoryPoolName) ;
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(memoryPoolName);
+ errorCount += checkNonEmpty(mbInfo);
+ System.out.println("getMBeanInfo\t\t" + mbInfo);
+ MemoryPoolMXBean memoryPool = null;
+
+ memoryPool =
+ JMX.newMXBeanProxy(mbsc,
+ memoryPoolName,
+ MemoryPoolMXBean.class,
+ true) ;
+ System.out.println("getCollectionUsage\t\t"
+ + memoryPool.getCollectionUsage());
+ System.out.println("getMemoryManagerNames\t\t"
+ + Arrays.deepToString(memoryPool.getMemoryManagerNames()));
+ System.out.println("getName\t\t"
+ + memoryPool.getName());
+ System.out.println("getPeakUsage\t\t"
+ + memoryPool.getPeakUsage());
+ System.out.println("getType\t\t"
+ + memoryPool.getType());
+ System.out.println("getUsage\t\t"
+ + memoryPool.getUsage());
+ System.out.println("isValid\t\t"
+ + memoryPool.isValid());
+ boolean supported = memoryPool.isUsageThresholdSupported() ;
+ System.out.println("isUsageThresholdSupported\t\t"
+ + supported);
+
+ if ( supported ) {
+ System.out.println("getUsageThreshold\t\t"
+ + memoryPool.getUsageThreshold());
+ System.out.println("isUsageThresholdExceeded\t\t"
+ + memoryPool.isUsageThresholdExceeded());
+ System.out.println("getUsageThresholdCount\t\t"
+ + memoryPool.getUsageThresholdCount());
+ }
+
+ supported = memoryPool.isCollectionUsageThresholdSupported() ;
+ System.out.println("isCollectionUsageThresholdSupported\t\t"
+ + supported);
+
+ if ( supported ) {
+ System.out.println("getCollectionUsageThreshold\t\t"
+ + memoryPool.getCollectionUsageThreshold());
+ System.out.println("getCollectionUsageThresholdCount\t\t"
+ + memoryPool.getCollectionUsageThresholdCount());
+ System.out.println("isCollectionUsageThresholdExceeded\t\t"
+ + memoryPool.isCollectionUsageThresholdExceeded());
+ }
+
+ memoryPool.resetPeakUsage();
+ }
+
+ System.out.println("---- OK\n") ;
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++ ;
+ System.out.println("---- ERROR\n") ;
+ }
+
+ return errorCount ;
+ }
+
+
+ private int checkNonEmpty(MBeanInfo mbi) {
+ if ( mbi.toString().length() == 0 ) {
+ System.out.println("(ERROR) MBeanInfo is empty !");
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/mxbean/MXBeanInteropTest2.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8058865
+ * @summary Checks access to test MXBean
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @compile Basic.java
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanInteropTest2
+ */
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.Attribute;
+import javax.management.JMX;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanConstructorInfo;
+import javax.management.MBeanServer;
+import java.lang.management.ManagementFactory;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+public class MXBeanInteropTest2 {
+
+ private static String BASIC_MXBEAN_CLASS_NAME = "Basic";
+
+ /*
+ * First Debug properties and arguments are collect in expected
+ * map (argName, value) format, then calls original test's run method.
+ */
+ public static void main(String args[]) throws Exception {
+
+ System.out.println("=================================================");
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+ Map<String, Object> map = Utils.parseParameters(args) ;
+
+ // Run test
+ MXBeanInteropTest2 test = new MXBeanInteropTest2();
+ test.run(map);
+
+ }
+
+ public void run(Map<String, Object> args) {
+
+ System.out.println("MXBeanInteropTest2::run: Start") ;
+ int errorCount = 0 ;
+
+ try {
+ // JMX MbeanServer used inside single VM as if remote.
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+ JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+ JMXConnectorServer cs =
+ JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+ cs.start();
+
+ JMXServiceURL addr = cs.getAddress();
+ JMXConnector cc = JMXConnectorFactory.connect(addr);
+ MBeanServerConnection mbsc = cc.getMBeanServerConnection();
+
+ // Prints all MBeans whatever the domain is.
+ printMBeans(mbsc) ;
+
+ // Call test body
+ errorCount += doBasicMXBeanTest(mbsc) ;
+
+ // Terminate the JMX Client
+ cc.close();
+
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ throw new RuntimeException(e);
+ }
+
+ if ( errorCount == 0 ) {
+ System.out.println("MXBeanInteropTest2::run: Done without any error") ;
+ } else {
+ System.out.println("MXBeanInteropTest2::run: Done with "
+ + errorCount
+ + " error(s)") ;
+ throw new RuntimeException("errorCount = " + errorCount);
+ }
+ }
+
+
+ /**
+ * Prints all MBeans whatever the domain is.
+ */
+ private static void printMBeans(MBeanServerConnection mbsc) throws Exception {
+ Set<ObjectName> set = mbsc.queryNames(null, null);
+ System.out.println("---- MBeans found :");
+
+ for (Iterator<ObjectName> iter = set.iterator(); iter.hasNext(); ) {
+ System.out.println(iter.next().toString());
+ }
+
+ System.out.println("\n") ;
+ }
+
+
+ private final int doBasicMXBeanTest(MBeanServerConnection mbsc) {
+ int errorCount = 0 ;
+ System.out.println("---- doBasicMXBeanTest") ;
+
+ try {
+ ObjectName objName =
+ new ObjectName("sqe:type=BasicMXBean") ;
+ mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName);
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(objName);
+ printMBeanInfo(mbInfo);
+ System.out.println("---- OK\n") ;
+ System.out.println("getMBeanInfo\t\t"
+ + mbInfo);
+ System.out.println("---- OK\n") ;
+
+ System.out.println("Check mxbean field in the MBeanInfo");
+ String mxbeanField =
+ (String)mbInfo.getDescriptor().getFieldValue(JMX.MXBEAN_FIELD);
+
+ if ( mxbeanField == null || ! mxbeanField.equals("true")) {
+ System.out.println("---- ERROR : Improper mxbean field value "
+ + mxbeanField);
+ errorCount++;
+ }
+ System.out.println("---- OK\n") ;
+
+ System.out.println("Set attribute ObjectNameAtt");
+ Attribute att = new Attribute("ObjectNameAtt", objName);
+ mbsc.setAttribute(objName, att);
+ ObjectName value =
+ (ObjectName)mbsc.getAttribute(objName, "ObjectNameAtt");
+
+ if ( ! value.equals(objName) ) {
+ errorCount++;
+ System.out.println("---- ERROR : setAttribute failed, got "
+ + value
+ + " while expecting "
+ + objName);
+ }
+ System.out.println("---- OK\n") ;
+
+ System.out.println("Call operation doNothing");
+ mbsc.invoke(objName, "doNothing", null, null);
+ System.out.println("---- OK\n") ;
+
+ System.out.println("Call operation getWeather");
+ Object weather = mbsc.invoke(objName,
+ "getWeather",
+ new Object[]{Boolean.TRUE},
+ new String[]{"boolean"});
+ System.out.println("Weather is " + weather);
+ System.out.println("---- OK\n") ;
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++ ;
+ System.out.println("---- ERROR\n") ;
+ }
+
+ return errorCount ;
+ }
+
+ private void printMBeanInfo(MBeanInfo mbInfo) {
+ System.out.println("Description " + mbInfo.getDescription());
+
+ for (MBeanConstructorInfo ctor : mbInfo.getConstructors()) {
+ System.out.println("Constructor " + ctor.getName());
+ }
+
+ for (MBeanAttributeInfo att : mbInfo.getAttributes()) {
+ System.out.println("Attribute " + att.getName()
+ + " [" + att.getType() + "]");
+ }
+
+ for (MBeanOperationInfo oper : mbInfo.getOperations()) {
+ System.out.println("Operation " + oper.getName());
+ }
+
+ for (MBeanNotificationInfo notif : mbInfo.getNotifications()) {
+ System.out.println("Notification " + notif.getName());
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/mxbean/MXBeanLoadingTest1.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8058865
+ * @summary Checks correct collection of MXBean's class after unregistration
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @run main/othervm/timeout=300 MXBeanLoadingTest1
+ */
+
+import java.lang.ref.WeakReference;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Arrays;
+import java.util.Map;
+import javax.management.Attribute;
+import javax.management.JMX;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MXBean;
+import javax.management.ObjectName;
+import javax.management.loading.PrivateMLet;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+
+public class MXBeanLoadingTest1 {
+
+ public static void main(String[] args) throws Exception {
+ MXBeanLoadingTest1 test = new MXBeanLoadingTest1();
+ test.run((Map<String, Object>)null);
+ }
+
+
+ public void run(Map<String, Object> args) {
+
+ System.out.println("MXBeanLoadingTest1::run: Start") ;
+
+ try {
+ System.out.println("We ensure no reference is retained on MXBean class"
+ + " after it is unregistered. We take time to perform"
+ + " some little extra check of Descriptors, MBean*Info.");
+
+ ClassLoader myClassLoader = MXBeanLoadingTest1.class.getClassLoader();
+
+ if (!(myClassLoader instanceof URLClassLoader)) {
+ String message = "(ERROR) Test's class loader is not " +
+ "a URLClassLoader";
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ URLClassLoader myURLClassLoader = (URLClassLoader) myClassLoader;
+ URL[] urls = myURLClassLoader.getURLs();
+ PrivateMLet mlet = new PrivateMLet(urls, null, false);
+ Class<?> shadowClass = mlet.loadClass(TestMXBean.class.getName());
+
+ if (shadowClass == TestMXBean.class) {
+ String message = "(ERROR) MLet got original TestMXBean, not shadow";
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ shadowClass = null;
+
+ MBeanServer mbs = MBeanServerFactory.createMBeanServer();
+ ObjectName mletName = new ObjectName("x:type=mlet");
+ mbs.registerMBean(mlet, mletName);
+
+ ObjectName testName = new ObjectName("x:type=test");
+ mbs.createMBean(Test.class.getName(), testName, mletName);
+
+ // That test fails because the MXBean instance is accessed via
+ // a delegate OpenMBean which has
+ ClassLoader testLoader = mbs.getClassLoaderFor(testName);
+
+ if (testLoader != mlet) {
+ System.out.println("MLet " + mlet);
+ String message = "(ERROR) MXBean's class loader is not MLet: "
+ + testLoader;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ testLoader = null;
+
+
+ // Cycle get/set/get of the attribute of type Luis.
+ // We check the set is effective.
+ CompositeData cd_B = (CompositeData)mbs.getAttribute(testName, "B");
+ CompositeType compType_B = cd_B.getCompositeType();
+
+ CompositeDataSupport cds_B =
+ new CompositeDataSupport(compType_B,
+ new String[]{"something"},
+ new Object[]{Integer.valueOf(13)});
+ Attribute myAtt = new Attribute("B", cds_B);
+ mbs.setAttribute(testName, myAtt);
+
+ CompositeData cd_B2 = (CompositeData)mbs.getAttribute(testName, "B");
+
+ if ( ((Integer)cd_B2.get("something")).intValue() != 13 ) {
+ String message = "(ERROR) The setAttribute of att B did not work;"
+ + " expect Luis.something = 13 but got "
+ + cd_B2.get("something");
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ MBeanInfo info = mbs.getMBeanInfo(testName);
+ String mxbeanField =
+ (String)info.getDescriptor().getFieldValue(JMX.MXBEAN_FIELD);
+
+ if ( mxbeanField == null || ! mxbeanField.equals("true")) {
+ String message = "(ERROR) Improper mxbean field value "
+ + mxbeanField;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ // Check the 2 attributes.
+ MBeanAttributeInfo[] attrs = info.getAttributes();
+
+ if ( attrs.length == 2 ) {
+ for (MBeanAttributeInfo mbai : attrs) {
+ String originalTypeFieldValue =
+ (String)mbai.getDescriptor().getFieldValue(JMX.ORIGINAL_TYPE_FIELD);
+ OpenType<?> openTypeFieldValue =
+ (OpenType<?>)mbai.getDescriptor().getFieldValue(JMX.OPEN_TYPE_FIELD);
+
+ if ( mbai.getName().equals("A") ) {
+ if ( !mbai.isReadable() || !mbai.isWritable()
+ || mbai.isIs()
+ || !mbai.getType().equals("int") ) {
+ String message = "(ERROR) Unexpected MBeanAttributeInfo for A "
+ + mbai;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ if ( ! originalTypeFieldValue.equals("int") ) {
+ String message = "(ERROR) Unexpected originalType in Descriptor for A "
+ + originalTypeFieldValue;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ if ( ! openTypeFieldValue.equals(SimpleType.INTEGER) ) {
+ String message = "(ERROR) Unexpected openType in Descriptor for A "
+ + originalTypeFieldValue;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ } else if ( mbai.getName().equals("B") ) {
+ if ( !mbai.isReadable() || !mbai.isWritable()
+ || mbai.isIs()
+ || !mbai.getType().equals("javax.management.openmbean.CompositeData") ) {
+ String message = "(ERROR) Unexpected MBeanAttributeInfo for B "
+ + mbai;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ if ( ! originalTypeFieldValue.equals(Luis.class.getName()) ) {
+ String message = "(ERROR) Unexpected originalType in Descriptor for B "
+ + originalTypeFieldValue;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ if ( ! openTypeFieldValue.equals(compType_B) ) {
+ String message = "(ERROR) Unexpected openType in Descriptor for B "
+ + compType_B;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ } else {
+ String message = "(ERROR) Unknown attribute name";
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ }
+ } else {
+ String message = "(ERROR) Unexpected MBeanAttributeInfo array"
+ + Arrays.deepToString(attrs);
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ // Check the MXBean operation.
+ MBeanOperationInfo[] ops = info.getOperations();
+ // The impact is ACTION_INFO as for a standard MBean it is UNKNOWN,
+ // logged 6320104.
+ if (ops.length != 1 || !ops[0].getName().equals("bogus")
+ || ops[0].getSignature().length > 0
+ || !ops[0].getReturnType().equals("void")) {
+ String message = "(ERROR) Unexpected MBeanOperationInfo array "
+ + Arrays.deepToString(ops);
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ String originalTypeFieldValue =
+ (String)ops[0].getDescriptor().getFieldValue(JMX.ORIGINAL_TYPE_FIELD);
+ OpenType<?> openTypeFieldValue =
+ (OpenType<?>)ops[0].getDescriptor().getFieldValue(JMX.OPEN_TYPE_FIELD);
+
+ if ( ! originalTypeFieldValue.equals("void") ) {
+ String message = "(ERROR) Unexpected originalType in Descriptor for bogus "
+ + originalTypeFieldValue;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ if ( ! openTypeFieldValue.equals(SimpleType.VOID) ) {
+ String message = "(ERROR) Unexpected openType in Descriptor for bogus "
+ + originalTypeFieldValue;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ // Check there is 2 constructors.
+ if (info.getConstructors().length != 2) {
+ String message = "(ERROR) Wrong number of constructors " +
+ "in introspected bean: " +
+ Arrays.asList(info.getConstructors());
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ // Check MXBean class name.
+ if (!info.getClassName().endsWith("Test")) {
+ String message = "(ERROR) Wrong info class name: " +
+ info.getClassName();
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ mbs.unregisterMBean(testName);
+ mbs.unregisterMBean(mletName);
+
+ WeakReference<PrivateMLet> mletRef =
+ new WeakReference<PrivateMLet>(mlet);
+ mlet = null;
+
+ System.out.println("MXBean registered and unregistered, waiting for " +
+ "garbage collector to collect class loader");
+
+ for (int i = 0; i < 10000 && mletRef.get() != null; i++) {
+ System.gc();
+ Thread.sleep(1);
+ }
+
+ if (mletRef.get() == null)
+ System.out.println("(OK) class loader was GC'd");
+ else {
+ String message = "(ERROR) Class loader was not GC'd";
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ throw new RuntimeException(e);
+ }
+
+ System.out.println("MXBeanLoadingTest1::run: Done without any error") ;
+ }
+
+
+ // I agree the use of the MXBean annotation and the MXBean suffix for the
+ // interface name are redundant but however harmless.
+ //
+ @MXBean(true)
+ public static interface TestMXBean {
+ public void bogus();
+ public int getA();
+ public void setA(int a);
+ public Luis getB();
+ public void setB(Luis mi);
+ }
+
+
+ public static class Test implements TestMXBean {
+ private Luis luis = new Luis() ;
+ public Test() {}
+ public Test(int x) {}
+
+ public void bogus() {}
+ public int getA() {return 0;}
+ public void setA(int a) {}
+ public Luis getB() {return this.luis;}
+ public void setB(Luis luis) {this.luis = luis;}
+ }
+
+
+ public static class Luis {
+ private int something = 0;
+ public Luis() {}
+ public int getSomething() {return something;}
+ public void setSomething(int v) {something = v;}
+ public void doNothing() {}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/mxbean/MXBeanNotifTest.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8058865
+ * @summary Checks MXBean proper registration both as its implementation class and interface
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @compile Basic.java
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanNotifTest -numOfNotifications 239 -timeForNotificationInSeconds 4
+ */
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import java.lang.management.ManagementFactory;
+
+import javax.management.Attribute;
+import javax.management.Descriptor;
+import javax.management.ImmutableDescriptor;
+import javax.management.MBeanServer;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+
+public class MXBeanNotifTest implements NotificationListener {
+
+ private static String BASIC_MXBEAN_CLASS_NAME = "Basic";
+ private static String BASIC_MXBEAN_INTERFACE_NAME = "BasicMXBean";
+
+ private long timeForNotificationInSeconds = 3L;
+ private int numOfNotifications = 1;
+ private BlockingQueue<Notification> notifList = null;
+ private int numOfNotifDescriptorElements = 13;
+
+ /*
+ * First Debug properties and arguments are collect in expected
+ * map (argName, value) format, then calls original test's run method.
+ */
+ public static void main(String args[]) throws Exception {
+
+ System.out.println("=================================================");
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+ Map<String, Object> map = Utils.parseParameters(args) ;
+
+ // Run test
+ MXBeanNotifTest test = new MXBeanNotifTest();
+ test.run(map);
+
+ }
+
+ protected void parseArgs(Map<String, Object> args) throws Exception {
+
+ String arg = null;
+
+ // Init numOfNotifications
+ // It is the number of notifications we should trigger and check.
+ arg = (String)args.get("-numOfNotifications") ;
+ if (arg != null) {
+ numOfNotifications = (new Integer(arg)).intValue();
+ }
+
+ // Init timeForNotificationInSeconds
+ // It is the maximum time in seconds we wait for each notification.
+ arg = (String)args.get("-timeForEachNotificationInSeconds") ;
+ if (arg != null) {
+ timeForNotificationInSeconds = (new Long(arg)).longValue();
+ }
+
+ }
+
+ public void run(Map<String, Object> args) {
+
+ System.out.println("MXBeanNotifTest::run: Start") ;
+ int errorCount = 0 ;
+
+ try {
+ parseArgs(args);
+ notifList = new ArrayBlockingQueue<Notification>(numOfNotifications);
+
+ // JMX MbeanServer used inside single VM as if remote.
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+ JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+ JMXConnectorServer cs =
+ JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+ cs.start();
+
+ JMXServiceURL addr = cs.getAddress();
+ JMXConnector cc = JMXConnectorFactory.connect(addr);
+ MBeanServerConnection mbsc = cc.getMBeanServerConnection();
+
+ // ----
+ System.out.println("MXBeanNotifTest::run: Create and register the MBean");
+ ObjectName objName = new ObjectName("sqe:type=Basic,protocol=rmi") ;
+ mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName);
+ System.out.println("---- OK\n") ;
+
+ // ----
+ System.out.println("MXBeanNotifTest::run: Add me as notification listener");
+ mbsc.addNotificationListener(objName, this, null, null);
+
+ // ----
+ System.out.println("MXBeanNotifTest::run: Retrieve the Descriptor"
+ + " that should be in MBeanNotificationInfo");
+ TabularData tabData =
+ (TabularData)mbsc.getAttribute(objName, "NotifDescriptorAsMapAtt");
+ Map<String, String> descrMap = new HashMap<>();
+
+ for (Iterator<?> it = tabData.values().iterator(); it.hasNext(); ) {
+ CompositeData compData = (CompositeData)it.next();
+ descrMap.put((String)compData.get("key"),
+ (String)compData.get("value"));
+ }
+
+ Descriptor refNotifDescriptor = new ImmutableDescriptor(descrMap);
+ System.out.println("---- OK\n") ;
+
+ // ----
+ // Because the MBean holding the targeted attribute is MXBean, we
+ // should use for the setAttribute a converted form for the
+ // attribute value as described by the MXBean mapping rules.
+ // This explains all that lovely stuff for creating a
+ // TabularDataSupport.
+ //
+ // WARNING : the MBeanInfo of the MXBean used on opposite side
+ // is computed when the MBean is registered.
+ // It means the Descriptor considered for the MBeanNotificationInfo
+ // is not the one we set in the lines below, it is too late.
+ // However, we check that set is harmless when we check
+ // the MBeanNotificationInfo.
+ //
+ System.out.println("MXBeanNotifTest::run: Set a Map<String, String>"
+ + " attribute");
+ String typeName =
+ "java.util.Map<java.lang.String,java.lang.String>";
+ String[] keyValue = new String[] {"key", "value"};
+ OpenType<?>[] openTypes =
+ new OpenType<?>[] {SimpleType.STRING, SimpleType.STRING};
+ CompositeType rowType = new CompositeType(typeName, typeName,
+ keyValue, keyValue, openTypes);
+ TabularType tabType = new TabularType(typeName, typeName,
+ rowType, new String[]{"key"});
+ TabularDataSupport convertedDescrMap =
+ new TabularDataSupport(tabType);
+
+ for (int i = 0; i < numOfNotifDescriptorElements; i++) {
+ Object[] descrValue = {"field" + i, "value" + i};
+ CompositeData data =
+ new CompositeDataSupport(rowType, keyValue, descrValue);
+ convertedDescrMap.put(data);
+ }
+
+ Attribute descrAtt =
+ new Attribute("NotifDescriptorAsMapAtt", convertedDescrMap);
+ mbsc.setAttribute(objName, descrAtt);
+ System.out.println("---- OK\n") ;
+
+ // ----
+ System.out.println("MXBeanNotifTest::run: Compare the Descriptor from"
+ + " the MBeanNotificationInfo against a reference");
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(objName);
+ errorCount += checkMBeanInfo(mbInfo, refNotifDescriptor);
+ System.out.println("---- DONE\n") ;
+
+ // ----
+ System.out.println("Check isInstanceOf(Basic)");
+
+ if ( ! mbsc.isInstanceOf(objName, BASIC_MXBEAN_CLASS_NAME) ) {
+ errorCount++;
+ System.out.println("---- ERROR isInstanceOf returned false\n") ;
+ } else {
+ System.out.println("---- OK\n") ;
+ }
+
+ // ----
+ System.out.println("Check isInstanceOf(BasicMXBean)");
+
+ if ( ! mbsc.isInstanceOf(objName, BASIC_MXBEAN_INTERFACE_NAME) ) {
+ errorCount++;
+ System.out.println("---- ERROR isInstanceOf returned false\n") ;
+ } else {
+ System.out.println("---- OK\n") ;
+ }
+
+ // ----
+ System.out.println("MXBeanNotifTest::run: Ask for "
+ + numOfNotifications + " notification(s)");
+ Object[] sendNotifParam = new Object[1];
+ String[] sendNotifSig = new String[]{"java.lang.String"};
+
+ for (int i = 0; i < numOfNotifications; i++) {
+ // Select which type of notification we ask for
+ if ( i % 2 == 0 ) {
+ sendNotifParam[0] = Basic.NOTIF_TYPE_0;
+ } else {
+ sendNotifParam[0] = Basic.NOTIF_TYPE_1;
+ }
+
+ // Trigger notification emission
+ mbsc.invoke(objName,
+ "sendNotification",
+ sendNotifParam,
+ sendNotifSig);
+
+ // Wait for it then check it when it comes early enough
+ Notification notif =
+ notifList.poll(timeForNotificationInSeconds,
+ TimeUnit.SECONDS) ;
+ // The very first notification is likely to come in slower than
+ // all the others. Because that test isn't targeting the speed
+ // notifications are delivered with, we prefer to secure it.
+ if (i == 0 && notif == null) {
+ System.out.println("MXBeanNotifTest::run: Wait extra "
+ + timeForNotificationInSeconds + " second(s) the "
+ + " very first notification");
+ notif = notifList.poll(timeForNotificationInSeconds,
+ TimeUnit.SECONDS);
+ }
+
+ if ( notif == null ) {
+ errorCount++;
+ System.out.println("---- ERROR No notification received"
+ + " within allocated " + timeForNotificationInSeconds
+ + " second(s) !");
+ } else {
+ errorCount +=
+ checkNotification(notif,
+ (String)sendNotifParam[0],
+ Basic.NOTIFICATION_MESSAGE,
+ objName);
+ }
+ }
+
+ int toc = 0;
+ while ( notifList.size() < 2 && toc < 10 ) {
+ Thread.sleep(499);
+ toc++;
+ }
+ System.out.println("---- DONE\n") ;
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ throw new RuntimeException(e);
+ }
+
+ if ( errorCount == 0 ) {
+ System.out.println("MXBeanNotifTest::run: Done without any error") ;
+ } else {
+ System.out.println("MXBeanNotifTest::run: Done with "
+ + errorCount
+ + " error(s)") ;
+ throw new RuntimeException("errorCount = " + errorCount);
+ }
+ }
+
+
+ private int checkMBeanInfo(MBeanInfo mbi, Descriptor refDescr) {
+ MBeanNotificationInfo[] notifsInfo = mbi.getNotifications();
+ int res = 0;
+
+ for (MBeanNotificationInfo mbni : notifsInfo) {
+ if ( mbni.getDescriptor().equals(refDescr) ) {
+ System.out.println("(OK)");
+ } else {
+ System.out.println("(ERROR) Descriptor of the notification is "
+ + mbni.getDescriptor()
+ + " as we expect "
+ + refDescr);
+ res++;
+ }
+ }
+
+ return res;
+ }
+
+
+ private int checkNotification(Notification notif,
+ String refType,
+ String refMessage,
+ ObjectName refSource) {
+ int res = 0;
+
+ Utils.debug(Utils.DEBUG_VERBOSE,
+ "\t getSource " + notif.getSource());
+ Utils.debug(Utils.DEBUG_VERBOSE,
+ "\t getMessage " + notif.getMessage());
+ Utils.debug(Utils.DEBUG_VERBOSE,
+ "\t getSequenceNumber " + notif.getSequenceNumber());
+ Utils.debug(Utils.DEBUG_VERBOSE,
+ "\t getTimeStamp " + notif.getTimeStamp());
+ Utils.debug(Utils.DEBUG_VERBOSE,
+ "\t getType " + notif.getType());
+ Utils.debug(Utils.DEBUG_VERBOSE,
+ "\t getUserData " + notif.getUserData());
+
+ if ( ! notif.getType().equals(refType) ) {
+ res++;
+ System.out.println("(ERROR) Type is not "
+ + refType + " in notification\n" + notif);
+ } else {
+ if ( notif.getType().equals(Basic.NOTIF_TYPE_0)
+ && ! (notif instanceof javax.management.Notification) ) {
+ res++;
+ System.out.println("(ERROR) Notification is not instance of "
+ + " javax.management.Notification but rather "
+ + notif.getClass().getName());
+ } else if ( notif.getType().equals(Basic.NOTIF_TYPE_1)
+ && ! (notif instanceof SqeNotification) ) {
+ res++;
+ System.out.println("(ERROR) Notification is not instance of "
+ + " javasoft.sqe.jmx.share.SqeNotification but rather "
+ + notif.getClass().getName());
+ }
+ }
+
+ if ( ! notif.getMessage().equals(refMessage) ) {
+ res++;
+ System.out.println("(ERROR) Message is not "
+ + refMessage + " in notification\n" + notif);
+ }
+
+ if ( ! notif.getSource().equals(refSource) ) {
+ res++;
+ System.out.println("(ERROR) Source is not "
+ + refSource + " in notification\n" + notif);
+ }
+
+ return res;
+ }
+
+ public void handleNotification(Notification notification, Object handback) {
+ Utils.debug(Utils.DEBUG_VERBOSE,
+ "MXBeanNotifTest::handleNotification: Received "
+ + notification);
+ notifList.add(notification);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/mxbean/MXBeanWeirdParamTest.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8058865
+ * @summary Checks that a serialized instance is not transmitted from an MXBean.
+ * All the communication should be done via Open Types
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @compile Basic.java
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanWeirdParamTest
+ */
+
+import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import java.lang.Process;
+import java.lang.management.ManagementFactory;
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+import javax.management.ObjectName;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JDKToolFinder;
+
+public class MXBeanWeirdParamTest {
+
+ private static String BASIC_MXBEAN_CLASS_NAME = "Basic";
+
+ private static final String CLIENT_CLASS_MAIN =
+ "MXBeanWeirdParamTest$ClientSide";
+
+ private JMXConnectorServer cs;
+
+ /*
+ * First Debug properties and arguments are collect in expected
+ * map (argName, value) format, then calls original test's run method.
+ */
+ public static void main(String args[]) throws Exception {
+
+ System.out.println("=================================================");
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+ Map<String, Object> map = Utils.parseParameters(args) ;
+
+ // Run test
+ MXBeanWeirdParamTest test = new MXBeanWeirdParamTest();
+ test.run(map);
+
+ }
+
+ /*
+ * Create the MBeansServe side of the test and returns its address
+ */
+ private JMXServiceURL createServerSide() throws Exception {
+ final int NINETY_SECONDS = 90;
+
+ // We will use the platform mbean server
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+ JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+ cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+ cs.start();
+
+ Utils.waitReady(cs, NINETY_SECONDS);
+
+ JMXServiceURL addr = cs.getAddress();
+ return addr;
+ }
+
+
+ /*
+ * Creating command-line for running subprocess JVM:
+ *
+ * JVM command line is like:
+ * {test_jdk}/bin/java {defaultopts} -cp {test.class.path} {testopts} main
+ *
+ * {defaultopts} are the default java options set by the framework.
+ *
+ */
+ private List<String> buildCommandLine() {
+ List<String> opts = new ArrayList<>();
+ opts.add(JDKToolFinder.getJDKTool("java"));
+ opts.addAll(Arrays.asList(jdk.testlibrary.Utils.getTestJavaOpts()));
+ // We need to set WEIRD_PARAM propertty on the client-side
+ opts.add("-DWEIRD_PARAM");
+ opts.add("-cp");
+ opts.add(System.getProperty("test.class.path", "test.class.path"));
+ opts.add(CLIENT_CLASS_MAIN);
+
+ return opts;
+ }
+
+ /**
+ * Runs MXBeanWeirdParamTest$ClientSide with the passed options and redirects
+ * subprocess standard I/O to the current (parent) process. This provides a
+ * trace of what happens in the subprocess while it is runnning (and before
+ * it terminates).
+ *
+ * @param serviceUrlStr string representing the JMX service Url to connect to.
+ */
+ private int runClientSide(String serviceUrlStr) throws Exception {
+
+ // Building command-line
+ List<String> opts = buildCommandLine();
+ opts.add(serviceUrlStr);
+
+ // Launch separate JVM subprocess
+ int exitCode = 0;
+ String[] optsArray = opts.toArray(new String[0]);
+ ProcessBuilder pb = new ProcessBuilder(optsArray);
+ Process p = ProcessTools.startProcess("MXBeanWeirdParamTest$ClientSide", pb);
+
+ // Handling end of subprocess
+ try {
+ exitCode = p.waitFor();
+ if (exitCode != 0) {
+ System.out.println(
+ "Subprocess unexpected exit value of [" + exitCode +
+ "]. Expected 0.\n");
+ }
+ } catch (InterruptedException e) {
+ System.out.println("Parent process interrupted with exception : \n " + e + " :" );
+
+ // Parent thread unknown state, killing subprocess.
+ p.destroyForcibly();
+
+ throw new RuntimeException(
+ "Parent process interrupted with exception : \n " + e + " :" );
+ } finally {
+ return exitCode;
+ }
+
+ }
+
+ public void run(Map<String, Object> args) throws Exception {
+
+ System.out.println("MXBeanWeirdParamTest::run: Start") ;
+ int errorCount = 0;
+
+ try {
+ // Initialise the server side
+ JMXServiceURL urlToUse = createServerSide();
+
+ // Run client side
+ errorCount = runClientSide(urlToUse.toString());
+
+ if ( errorCount == 0 ) {
+ System.out.println("MXBeanWeirdParamTest::run: Done without any error") ;
+ } else {
+ System.out.println("MXBeanWeirdParamTest::run: Done with "
+ + errorCount
+ + " error(s)") ;
+ throw new RuntimeException("errorCount = " + errorCount);
+ }
+
+ cs.stop();
+
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ private static class ClientSide {
+ public static void main(String args[]) throws Exception {
+
+ int errorCount = 0 ;
+ String msgTag = "ClientSide::main: ";
+
+ try {
+
+ // Get a connection to remote mbean server
+ JMXServiceURL addr = new JMXServiceURL(args[0]);
+ JMXConnector cc = JMXConnectorFactory.connect(addr);
+ MBeanServerConnection mbsc = cc.getMBeanServerConnection();
+
+ // ----
+ System.out.println(msgTag + "Create and register the MBean");
+ ObjectName objName = new ObjectName("sqe:type=Basic,protocol=rmi") ;
+ mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName);
+ System.out.println(msgTag +"---- OK\n") ;
+
+ // ----
+ System.out.println(msgTag +"Get attribute SqeParameterAtt on our MXBean");
+ Object result = mbsc.getAttribute(objName, "SqeParameterAtt");
+ System.out.println(msgTag +"(OK) Got result of class "
+ + result.getClass().getName());
+ System.out.println(msgTag +"Received CompositeData is " + result);
+ System.out.println(msgTag +"---- OK\n") ;
+
+ // ----
+ // We use the value returned by getAttribute to perform the invoke.
+ System.out.println(msgTag +"Call operation doWeird on our MXBean [1]");
+ mbsc.invoke(objName, "doWeird",
+ new Object[]{result},
+ new String[]{"javax.management.openmbean.CompositeData"});
+ System.out.println(msgTag +"---- OK\n") ;
+
+ // ----
+ // We build the CompositeData ourselves that time.
+ System.out.println(msgTag +"Call operation doWeird on our MXBean [2]");
+ String typeName = "SqeParameter";
+ String[] itemNames = new String[] {"glop"};
+ OpenType<?>[] openTypes = new OpenType<?>[] {SimpleType.STRING};
+ CompositeType rowType = new CompositeType(typeName, typeName,
+ itemNames, itemNames, openTypes);
+ Object[] itemValues = {"HECTOR"};
+ CompositeData data =
+ new CompositeDataSupport(rowType, itemNames, itemValues);
+ TabularType tabType = new TabularType(typeName, typeName,
+ rowType, new String[]{"glop"});
+ TabularDataSupport tds = new TabularDataSupport(tabType);
+ tds.put(data);
+ System.out.println(msgTag +"Source CompositeData is " + data);
+ mbsc.invoke(objName, "doWeird",
+ new Object[]{data},
+ new String[]{"javax.management.openmbean.CompositeData"});
+ System.out.println(msgTag +"---- OK\n") ;
+
+ // ----
+ System.out.println(msgTag +"Unregister the MBean");
+ mbsc.unregisterMBean(objName);
+ System.out.println(msgTag +"---- OK\n") ;
+
+ // Terminate the JMX Client
+ cc.close();
+
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++;
+ throw new RuntimeException(e);
+ } finally {
+ System.exit(errorCount);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/mxbean/SqeDescriptorKey.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import javax.management.DescriptorKey;
+
+/**
+ * That annotation is usable everywhere DescriptorKey is (and even more).
+ * It is for use to test that you can retrieve the SqeDescriptorKey into the
+ * appropriate Descriptor instances as built by the JMX runtime.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface SqeDescriptorKey {
+ @DescriptorKey("sqeDescriptorKey")
+ String value();
+
+ // List descriptor fields that may be added or may be updated
+ // when retrieving an MBeanInfo using a JMXWS connection compared to the
+ // MBeanInfo returned by a local MBeanServer.
+ // The annotation format is :
+ // <descriptorFieldName>=<descriptorFieldValue>
+ // The values actually handled by the test suite are :
+ // openType=SimpleType.VOID
+ @DescriptorKey("descriptorFields")
+ String[] descriptorFields() default {};
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/mxbean/SqeNotification.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 javax.management.Notification;
+
+/**
+ * Could hold someday a specific semantic.
+ * For now it is used to have a Notification which of another class, no more.
+ */
+public class SqeNotification extends Notification {
+
+ /** Creates a new instance of SqeNotification */
+ public SqeNotification(String type, Object source, long sequenceNumber) {
+ super(type, source, sequenceNumber);
+ }
+
+ /** Creates a new instance of SqeNotification */
+ public SqeNotification(String type, Object source, long sequenceNumber,
+ long timeStamp) {
+ super(type, source, sequenceNumber, timeStamp);
+ }
+
+ /** Creates a new instance of SqeNotification */
+ public SqeNotification(String type, Object source, long sequenceNumber,
+ long timeStamp, String message) {
+ super(type, source, sequenceNumber, timeStamp, message);
+ }
+
+ /** Creates a new instance of SqeNotification */
+ public SqeNotification(String type, Object source, long sequenceNumber,
+ String message) {
+ super(type, source, sequenceNumber, message);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/mxbean/SqeParameter.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.Serializable;
+
+/**
+ * That class is to use as an MBean operation parameter or returned value.
+ * The property Glop with its public getter + setter is only there to be
+ * reconstructible following MXBean specification, so that SqeParameter can be
+ * used for what it is designed to.
+ */
+public class SqeParameter implements Serializable {
+
+ private static boolean weird;
+ private String glop;
+
+ static {
+ if ( System.getProperty("WEIRD_PARAM") != null ) {
+ weird = true;
+ }
+ }
+
+ /**
+ * Creates a new instance of SqeParameter.
+ * <br>When the Java property WEIRD_PARAM is set, that constructor
+ * throws an exception.
+ * <br>That can be used to ensure the class is instantiated on server side
+ * but never on client side.
+ */
+ public SqeParameter() throws Exception {
+ if ( weird ) {
+ throw new Exception();
+ }
+ }
+
+ public String getGlop() {
+ return glop;
+ }
+
+ public void setGlop(String value) {
+ glop = value;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/mxbean/Utils.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Properties;
+import java.lang.reflect.Method;
+import javax.management.remote.JMXConnectorServerMBean;
+
+// utility class for MXBean* tests coming from JMX Tonga test suite
+class Utils {
+
+ // DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property
+ private static final String DEBUG_HEADER = "[debug] ";
+
+ // DEBUG levels
+ private static int selectedDebugLevel = 0;
+ static final int DEBUG_STANDARD = 1;
+ static final int DEBUG_VERBOSE = 2; // Mainly used for stress tests
+ static final int DEBUG_ALL = DEBUG_STANDARD | DEBUG_VERBOSE;
+
+ static void parseDebugProperties() {
+ int level = 0;
+ Properties p = System.getProperties();
+
+ // get selected levels
+ if (p.getProperty("DEBUG_STANDARD") != null) {
+ level |= DEBUG_STANDARD;
+ }
+
+ if (p.getProperty("DEBUG_VERBOSE") != null) {
+ level |= DEBUG_VERBOSE;
+ }
+
+ if (p.getProperty("DEBUG_ALL") != null) {
+ level |= DEBUG_ALL;
+ }
+
+ selectedDebugLevel = level;
+ }
+
+ /**
+ * Reproduces the original parsing and collection of test parameters
+ * from the DTonga JMX test suite.
+ *
+ * Collects passed args and returns them in a map(argname, value) structure,
+ * which will be then propagated as necessary to various called methods.
+ */
+ static Map<String, Object> parseParameters(String args[])
+ throws Exception {
+ Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Start");
+ HashMap<String, Object> map = new HashMap<>();
+
+ for ( int i = 0; i < args.length; i++ ) {
+ if ( args[i].trim().startsWith("-") ) {
+ if ((i+1) < args.length && !args[i+1].startsWith("-") ) {
+ Utils.debug(DEBUG_STANDARD,
+ "TestRoot::parseParameters: added in map = " +
+ args[i] +
+ " with value " +
+ args[i+1]) ;
+ map.put(args[i].trim(), args[i+1].trim()) ;
+ } else if ((i+1) < args.length && args[i+1].startsWith("-") ||
+ (i+1) == args.length ) {
+ Utils.debug(DEBUG_STANDARD,
+ "TestRoot::parseParameters: added in map = " +
+ args[i] +
+ " with null value") ;
+ map.put(args[i].trim(), null) ;
+ } else {
+ System.out.println(
+ "TestRoot::parseParameters: (WARNING) not added in map = " +
+ args[i]) ;
+ }
+ }
+ }
+
+ Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Done") ;
+ return map ;
+ }
+
+ /**
+ * This method is to be used in all tests to print anything
+ * that is temporary.
+ * Printing is done only when debug is activated by the property DEBUG.
+ * Printing depends also on the DEBUG_LEVEL property.
+ * Here it encapsulates a System.out.println.
+ */
+ public static void debug(int level, String line) {
+ if ((selectedDebugLevel & level) != 0) {
+ System.out.println(DEBUG_HEADER + line);
+ }
+ }
+
+ /**
+ * Do print stack trace when withStack is true.
+ * Does try to call getTargetException() and getTargetError() then
+ * print embedded stacks in the case of an Exception wrapping
+ * another Exception or an Error. Recurse until no more wrapping
+ * is found.
+ */
+ public static void printThrowable(Throwable theThro, boolean withStack) {
+ try {
+ if (withStack) {
+ theThro.printStackTrace(System.out);
+ }
+ if (theThro instanceof Exception) {
+ Exception t = (Exception) theThro;
+ Method target = null;
+ String blank = " ";
+ try {
+ target = t.getClass().getMethod("getTargetException",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetException method could be there or not
+ }
+ System.out.println(blank + t.getClass() + "==>" + t.getMessage());
+ while (target != null) {
+ try {
+ t = (Exception) target.invoke(t,
+ (java.lang.Object[]) null);
+ } catch (Exception ee) {
+ t = null;
+ }
+ try {
+ if (t != null) {
+ blank = blank + " ";
+ System.out.println(blank + t.getClass() + "==>" +
+ t.getMessage());
+ try {
+ target =
+ t.getClass().getMethod("getTargetException",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetException method could be there or not }
+ }
+ } else {
+ target = null;
+ }
+ } catch (Exception ee) {
+ target = null;
+ }
+ }
+
+ // We may have exceptions wrapping an Error then it is
+ // getTargetError that is likely to be called
+ try {
+ target = ((Exception) theThro).getClass().getMethod("getTargetError",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetError method could be there or not
+ }
+ Throwable err = theThro;
+ while (target != null) {
+ try {
+ err = (Error) target.invoke(err,
+ (java.lang.Object[]) null);
+ } catch (Exception ee) {
+ err = null;
+ }
+ try {
+ if (err != null) {
+ blank = blank + " ";
+ System.out.println(blank + err.getClass() + "==>" +
+ err.getMessage());
+ if (withStack) {
+ err.printStackTrace(System.out);
+ }
+ try {
+ target = err.getClass().getMethod("getTargetError",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetError method could be there or not
+ }
+ } else {
+ target = null;
+ }
+ } catch (Exception ee) {
+ target = null;
+ }
+ }
+ } else {
+ System.out.println("Throwable is : " + theThro);
+ }
+ } catch (Throwable x) {
+ System.out.println("Exception : raised in printException : " + x);
+ }
+ }
+
+ /**
+ * Wait up to maxTimeInSeconds second(s) the given JMX connector server
+ * comes up (which means isActive returns true).
+ * If it fails to do so we throw a RunTime exception.
+ */
+ public static void waitReady(JMXConnectorServerMBean server,
+ int maxTimeInSeconds) throws Exception {
+ int elapsed = 0;
+
+ while (!server.isActive() && elapsed < maxTimeInSeconds) {
+ Thread.sleep(1000);
+ elapsed++;
+ }
+
+ if (server.isActive()) {
+ String message = "Utils::waitReady: JMX connector server came up";
+ if ( elapsed == 0) {
+ message += " immediately";
+ } else {
+ message += " after " + elapsed + " seconds";
+ }
+ message += " [" + server.getAddress() + "]";
+ Utils.debug(DEBUG_STANDARD, message);
+ } else {
+ String message = "Utils::waitReady: (ERROR) JMX connector" +
+ " server didn't come up after " + elapsed + " seconds [" +
+ server.getAddress() + "]";
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/query/QueryData.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+public abstract class QueryData {
+ protected int intValue = 9;
+ protected long longValue = 9L;
+ protected Integer integerValue = Integer.valueOf(9);
+ protected boolean booleanValue = true;
+ protected double doubleValue = 9D;
+ protected float floatValue = 9.0F;
+ protected String stringValue = "9";
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/query/QueryFactory.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.ArrayList;
+
+import javax.management.Query;
+import javax.management.QueryExp;
+import javax.management.ValueExp;
+
+/**
+ * Class used for building QueryExp instances of all every possible type
+ * in terms of JMX API members; note that several JMX classes are private
+ * and appears in the JDK API only by their serial form.
+ * Comments in each case of the big switch in method getQuery() details which
+ * API member we cover with a given query.
+ */
+public class QueryFactory extends QueryData {
+
+ private String mbeanClassName = "";
+ private String primitiveIntAttName = "IntAtt";
+ private String primitiveLongAttName = "LongAtt";
+ private String integerAttName = "IntegerAtt";
+ private String primitiveBooleanAttName = "BooleanAtt";
+ private String primitiveDoubleAttName = "DoubleAtt";
+ private String primitiveFloatAttName = "FloatAtt";
+ private String stringAttName = "StringAtt";
+ private ArrayList<QueryExp> queries = new ArrayList<QueryExp>();
+
+ /**
+ * Creates a new instance of QueryFactory.
+ * The name is the fully qualified class name of an MBean.
+ * There is severe constraints on that MBean that must:
+ * <ul>
+ * <li>extend QueryData in order to inherit attribute values.
+ * <li>define a RW attribute IntAtt of type int
+ * initialized to QueryData.longValue
+ * <li>define a RW attribute LongAtt of type long
+ * initialized to QueryData.intValue
+ * <li>define a RW attribute IntegerAtt of type Integer
+ * initialized to QueryData.integerValue
+ * <li>define a RW attribute BooleanAtt of type boolean
+ * initialized to QueryData.booleanValue
+ * <li>define a RW attribute DoubleAtt of type double
+ * initialized to QueryData.doubleValue
+ * <li>define a RW attribute FloatAtt of type float
+ * initialized to QueryData.floatValue
+ * <li>define a RW attribute StringAtt of type String
+ * initialized to QueryData.stringValue
+ * </ul>
+ */
+ public QueryFactory(String name) {
+ this.mbeanClassName = name;
+ }
+
+ /**
+ * Returns the highest index value the method getQuery supports.
+ * WARNING : returns 0 if buildQueries haven't been called first !
+ */
+ public int getSize() {
+ return queries.size();
+ }
+
+ /**
+ * Populates an ArrayList of QueryExp.
+ * Lowest index is 1.
+ * Highest index is returned by getSize().
+ * <br>The queries numbered 1 to 23 allow to cover all the underlying
+ * Java classes of the JMX API used to build queries.
+ */
+ public void buildQueries() {
+ if ( queries.size() == 0 ) {
+ int smallerIntValue = intValue - 1;
+ int biggerIntValue = intValue + 1;
+
+ // case 1:
+ // True if the MBean is of class mbeanClassName
+ // We cover javax.management.InstanceOfQueryExp
+ queries.add(Query.isInstanceOf(Query.value(mbeanClassName)));
+
+ // case 2:
+ // True if the MBean is of class mbeanClassName
+ // We cover javax.management.MatchQueryExp and
+ // javax.management.ClassAttributeValueExp
+ queries.add(Query.match(Query.classattr(),
+ Query.value(mbeanClassName)));
+
+ // case 3:
+ // True if an attribute named primitiveIntAttName of type int has
+ // the value intValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to EQ and javax.management.NumericValueExp
+ queries.add(Query.eq(Query.attr(primitiveIntAttName),
+ Query.value(intValue)));
+
+ // case 4:
+ // True if an attribute named primitiveLongAttName of type long has
+ // the value longValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to EQ and javax.management.NumericValueExp
+ queries.add(Query.eq(Query.attr(primitiveLongAttName),
+ Query.value(longValue)));
+
+ // case 5:
+ // True if an attribute named primitiveDoubleAttName of type double
+ // has the value doubleValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to EQ and javax.management.NumericValueExp
+ queries.add(Query.eq(Query.attr(primitiveDoubleAttName),
+ Query.value(doubleValue)));
+
+ // case 6:
+ // True if an attribute named primitiveFloatAttName of type float
+ // has the value floatValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to EQ and javax.management.NumericValueExp
+ queries.add(Query.eq(Query.attr(primitiveFloatAttName),
+ Query.value(floatValue)));
+
+ // case 7:
+ // True if an attribute named primitiveIntAttName of type int is
+ // hold by an MBean of class mbeanClassName and has
+ // the value intValue
+ // We cover javax.management.QualifiedAttributeValueExp
+ queries.add(Query.eq(Query.attr(mbeanClassName, primitiveIntAttName),
+ Query.value(intValue)));
+
+ // case 8:
+ // True if an attribute named stringAttName of type String has
+ // the value stringValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to EQ and javax.management.StringValueExp
+ queries.add(Query.eq(Query.attr(stringAttName),
+ Query.value(stringValue)));
+
+ // case 9:
+ // True if an attribute named integerAttName of type Integer has
+ // the value integerValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to EQ and javax.management.NumericValueExp
+ queries.add(Query.eq(Query.attr(integerAttName),
+ Query.value(integerValue)));
+
+ // case 10:
+ // True if an attribute named primitiveBooleanAttName of type boolean
+ // has the value booleanValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to EQ and javax.management.BooleanValueExp
+ queries.add(Query.eq(Query.attr(primitiveBooleanAttName),
+ Query.value(booleanValue)));
+
+ // case 11:
+ // True if an attribute named primitiveIntAttName of type int has
+ // not the value smallerIntValue
+ // We cover javax.management.NotQueryExp
+ queries.add(Query.not(Query.eq(Query.attr(primitiveIntAttName),
+ Query.value(smallerIntValue))));
+
+ // case 12:
+ // True if either
+ // an attribute named primitiveIntAttName of type int has
+ // the value intValue
+ // or
+ // an attribute named primitiveLongAttName of type long has
+ // the value longValue
+ // We cover javax.management.OrQueryExp
+ queries.add(Query.or(
+ Query.eq(Query.attr(primitiveIntAttName),
+ Query.value(intValue)),
+ Query.eq(Query.attr(primitiveLongAttName),
+ Query.value(longValue))));
+
+ // case 13:
+ // True if
+ // an attribute named primitiveIntAttName of type int has
+ // the value intValue
+ // and
+ // an attribute named primitiveLongAttName of type long has
+ // the value longValue
+ // We cover javax.management.AndQueryExp
+ queries.add(Query.and(
+ Query.eq(Query.attr(primitiveIntAttName),
+ Query.value(intValue)),
+ Query.eq(Query.attr(primitiveLongAttName),
+ Query.value(longValue))));
+
+ // case 14:
+ // True if an attribute named primitiveIntAttName of type int has
+ // the value intValue
+ // We cover javax.management.InQueryExp
+ ValueExp[] inArray = {Query.value(intValue)};
+ queries.add(Query.in(Query.attr(primitiveIntAttName), inArray));
+
+ // case 15:
+ // True if an attribute named primitiveIntAttName of type int has
+ // its value in between smallerIntValue and biggerIntValue
+ // We cover javax.management.BetweenRelQueryExp
+ queries.add(Query.between(Query.attr(primitiveIntAttName),
+ Query.value(smallerIntValue),
+ Query.value(biggerIntValue)));
+
+ // case 16:
+ // True if an attribute named primitiveIntAttName of type int has
+ // a value greater than smallerIntValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to GT
+ queries.add(Query.gt(Query.attr(primitiveIntAttName),
+ Query.value(smallerIntValue)));
+
+ // case 17:
+ // True if an attribute named primitiveIntAttName of type int has
+ // a value greater or equal to smallerIntValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to GE
+ queries.add(Query.geq(Query.attr(primitiveIntAttName),
+ Query.value(smallerIntValue)));
+
+ // case 18:
+ // True if an attribute named primitiveIntAttName of type int has
+ // a value smaller than biggerIntValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to LT
+ queries.add(Query.lt(Query.attr(primitiveIntAttName),
+ Query.value(biggerIntValue)));
+
+ // case 19:
+ // True if an attribute named primitiveIntAttName of type int has
+ // a value smaller or equal to biggerIntValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to LE
+ queries.add(Query.leq(Query.attr(primitiveIntAttName),
+ Query.value(biggerIntValue)));
+
+ // case 20:
+ // True if an attribute named primitiveIntAttName of type int has
+ // a value equal to intValue minus zero
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to MINUS
+ queries.add(Query.eq(Query.attr(primitiveIntAttName),
+ Query.minus(Query.value(intValue), Query.value(0))));
+
+ // case 21:
+ // True if an attribute named primitiveIntAttName of type int has
+ // a value equal to intValue plus zero
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to PLUS
+ queries.add(Query.eq(Query.attr(primitiveIntAttName),
+ Query.plus(Query.value(intValue), Query.value(0))));
+
+ // case 22:
+ // True if an attribute named primitiveIntAttName of type int has
+ // a value equal to intValue divided by one
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to DIV
+ queries.add(Query.eq(Query.attr(primitiveIntAttName),
+ Query.div(Query.value(intValue), Query.value(1))));
+
+ // case 23:
+ // True if an attribute named primitiveIntAttName of type int has
+ // a value equal to intValue multiplicated by one
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to TIMES
+ queries.add(Query.eq(Query.attr(primitiveIntAttName),
+ Query.times(Query.value(intValue), Query.value(1))));
+
+ // case 24:
+ // That query is a complex one that combines within a big AND
+ // queries with index 2 to 23 inclusive. But because a List is
+ // zero based, we must decrement all indexes by 1 when retrieving
+ // any previously stored query.
+ QueryExp q2_3 = Query.and(queries.get(2-1), queries.get(3-1));
+ QueryExp q4_5 = Query.and(queries.get(4-1), queries.get(5-1));
+ QueryExp q6_7 = Query.and(queries.get(6-1), queries.get(7-1));
+ QueryExp q8_9 = Query.and(queries.get(8-1), queries.get(9-1));
+ QueryExp q10_11 = Query.and(queries.get(10-1), queries.get(11-1));
+ QueryExp q12_13 = Query.and(queries.get(12-1), queries.get(13-1));
+ QueryExp q14_15 = Query.and(queries.get(14-1), queries.get(15-1));
+ QueryExp q16_17 = Query.and(queries.get(16-1), queries.get(17-1));
+ QueryExp q18_19 = Query.and(queries.get(18-1), queries.get(19-1));
+ QueryExp q20_21 = Query.and(queries.get(20-1), queries.get(21-1));
+ QueryExp q22_23 = Query.and(queries.get(22-1), queries.get(23-1));
+ QueryExp q2_5 = Query.and(q2_3, q4_5);
+ QueryExp q6_9 = Query.and(q6_7, q8_9);
+ QueryExp q10_13 = Query.and(q10_11, q12_13);
+ QueryExp q14_17 = Query.and(q14_15, q16_17);
+ QueryExp q18_21 = Query.and(q18_19, q20_21);
+ QueryExp q2_9 = Query.and(q2_5, q6_9);
+ QueryExp q10_17 = Query.and(q10_13, q14_17);
+ QueryExp q18_23 = Query.and(q18_21, q22_23);
+ QueryExp q2_17 = Query.and(q2_9, q10_17);
+ queries.add(Query.and(q2_17, q18_23));
+
+ // case 25:
+ // Complex query mixing AND and OR.
+ queries.add(Query.or(q6_9, q18_23));
+ }
+ }
+
+ /**
+ * Returns a QueryExp taken is the ArrayList populated by buildQueries().
+ * Lowest index is 1.
+ * Highest index is returned by getSize().
+ * <br>The queries numbered 1 to 23 allow to cover all the underlying
+ * Java classes of the JMX API used to build queries.
+ */
+ public QueryExp getQuery(int index) {
+ return queries.get(index - 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/query/ServerDelegate.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.management.remote.JMXServiceURL ;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.StandardMBean;
+
+/**
+ * This class defines an MBean that can be registered and used on client side
+ * to handle informations or properties of the remote server.
+ *
+ * For example, this MBean can store IOR addresses
+ * of RMI/IIOP connector(s) used in a test.
+ *
+ * That MBean might not be used for testing purpose itself.
+ */
+public class ServerDelegate implements ServerDelegateMBean, MBeanRegistration {
+
+ private MBeanServer mbeanServer = null;
+ private List<JMXServiceURL> addresses = null;
+ private String port;
+ private static String javaVersion = System.getProperty("java.version");
+ private int sqeJmxwsCredentialsProviderCallCount = 0;
+ private String jmxwsCredentialsProviderUrl = null;
+ private int testJMXAuthenticatorCallCount = 0;
+ private Principal testJMXAuthenticatorPrincipal = null;
+
+ @SqeDescriptorKey("NO PARAMETER CONSTRUCTOR ServerDelegate")
+ public ServerDelegate() {
+ addresses = new ArrayList<JMXServiceURL>();
+ }
+
+ public ObjectName preRegister(MBeanServer server, ObjectName name)
+ throws Exception {
+ // Initialize MBeanServer attribute
+ mbeanServer = server;
+ return name;
+ }
+ public void postRegister(Boolean registrationDone) {
+ }
+ public void preDeregister() throws Exception {
+ }
+ public void postDeregister() {
+ }
+
+ public void addAddress(JMXServiceURL url) {
+ addresses.add(url) ;
+ }
+
+ public List<JMXServiceURL> getAddresses() {
+ return addresses ;
+ }
+
+ public void setPort(String p) {
+ port = p ;
+ }
+
+ public String getPort() {
+ return port ;
+ }
+
+ public String getJavaVersion() {
+ return javaVersion;
+ }
+
+ public void sqeJmxwsCredentialsProviderCalled() {
+ sqeJmxwsCredentialsProviderCallCount++;
+ }
+
+ public int getSqeJmxwsCredentialsProviderCallCount() {
+ return sqeJmxwsCredentialsProviderCallCount;
+ }
+
+ public void setJmxwsCredentialsProviderUrl(String url) {
+ jmxwsCredentialsProviderUrl = url;
+ }
+
+ public String getJmxwsCredentialsProviderUrl() {
+ return jmxwsCredentialsProviderUrl;
+ }
+
+ public void testJMXAuthenticatorCalled() {
+ testJMXAuthenticatorCallCount++;
+ }
+
+ public int getTestJMXAuthenticatorCallCount() {
+ return testJMXAuthenticatorCallCount;
+ }
+
+ public void setTestJMXAuthenticatorPrincipal(Principal principal) {
+ testJMXAuthenticatorPrincipal = principal;
+ }
+
+ public String getTestJMXAuthenticatorPrincipalString() {
+ if ( testJMXAuthenticatorPrincipal != null ) {
+ return testJMXAuthenticatorPrincipal.toString();
+ }
+
+ return null;
+ }
+
+ /**
+ * Instantiates and registers a StandardMBean in the MBean server.
+ *
+ * @param implementationClassName
+ * The implementation class name of the MBean.
+ * @param interfaceClassName
+ * The management interface class name of the MBean.
+ * @param isMXBean
+ * If true, the resultant MBean is an MXBean.
+ * @param name
+ * The object name of the StandardMBean.
+ */
+ @SuppressWarnings("unchecked")
+ public void createStandardMBean(
+ String implementationClassName,
+ String interfaceClassName,
+ boolean isMXBean,
+ ObjectName name)
+ throws Exception {
+
+ Object implementation =
+ Class.forName(implementationClassName).newInstance();
+ Class<Object> interfaceClass = interfaceClassName == null ? null :
+ (Class<Object>)Class.forName(interfaceClassName);
+
+ // Create the StandardMBean
+ StandardMBean standardMBean = new StandardMBean(
+ implementation,
+ interfaceClass,
+ isMXBean);
+
+ // Register the StandardMBean
+ mbeanServer.registerMBean(standardMBean, name);
+ }
+
+ /**
+ * Instantiates and registers a StandardMBean in the MBean server.
+ * The object will use standard JMX design pattern to determine
+ * the management interface associated with the given implementation.
+ */
+ @SuppressWarnings("unchecked")
+ public void createStandardMBean(
+ String implementationClassName,
+ boolean isMXBean,
+ ObjectName name)
+ throws Exception {
+
+ createStandardMBean(implementationClassName, null, isMXBean, name);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/query/ServerDelegateMBean.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.Principal;
+import java.util.List;
+
+import javax.management.remote.JMXServiceURL ;
+import javax.management.ObjectName;
+
+@SqeDescriptorKey("INTERFACE ServerDelegateMBean")
+public interface ServerDelegateMBean {
+ @SqeDescriptorKey("ATTRIBUTE Address")
+ public void addAddress(JMXServiceURL url);
+
+ @SqeDescriptorKey("ATTRIBUTE Address")
+ public List<JMXServiceURL> getAddresses();
+
+ public String getPort();
+ public void setPort(String p);
+
+ public String getJavaVersion();
+
+ public void sqeJmxwsCredentialsProviderCalled();
+ public int getSqeJmxwsCredentialsProviderCallCount();
+
+ public void setJmxwsCredentialsProviderUrl(String url);
+ public String getJmxwsCredentialsProviderUrl();
+
+ public void testJMXAuthenticatorCalled();
+ public int getTestJMXAuthenticatorCallCount();
+
+ public void setTestJMXAuthenticatorPrincipal(Principal principal);
+ public String getTestJMXAuthenticatorPrincipalString();
+
+ public void createStandardMBean(
+ String implementationClassName,
+ String interfaceClassName,
+ boolean isMXBean,
+ ObjectName name)
+ throws Exception;
+
+ public void createStandardMBean(
+ String implementationClassName,
+ boolean isMXBean,
+ ObjectName name)
+ throws Exception;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/query/SqeDescriptorKey.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import javax.management.DescriptorKey;
+
+/**
+ * That annotation is usable everywhere DescriptorKey is (and even more).
+ * It is for use to test that you can retrieve the SqeDescriptorKey into the
+ * appropriate Descriptor instances as built by the JMX runtime.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface SqeDescriptorKey {
+ @DescriptorKey("sqeDescriptorKey")
+ String value();
+
+ // List descriptor fields that may be added or may be updated
+ // when retrieving an MBeanInfo using a JMXWS connection compared to the
+ // MBeanInfo returned by a local MBeanServer.
+ // The annotation format is :
+ // <descriptorFieldName>=<descriptorFieldValue>
+ // The values actually handled by the test suite are :
+ // openType=SimpleType.VOID
+ @DescriptorKey("descriptorFields")
+ String[] descriptorFields() default {};
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/query/SupportedQueryTypesTest.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,471 @@
+/*
+ * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8058865
+ * @summary Tests most of the existing query types.
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @compile TestQuery.java
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SupportedQueryTypesTest -mbeanClassName TestQuery
+ */
+
+import java.util.Map ;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Properties;
+import java.lang.reflect.Method;
+
+import java.lang.management.ManagementFactory;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectInstance;
+import javax.management.ObjectName ;
+import javax.management.QueryExp;
+
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+public class SupportedQueryTypesTest {
+
+ protected String mbeanClassName = null;
+
+ private MBeanServerConnection mbsc = null;
+
+
+ /*
+ * First Debug properties and arguments are collect in expected
+ * map (argName, value) format, then calls original test's run method.
+ */
+ public static void main(String args[]) throws Exception {
+
+ System.out.println("=================================================");
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+ Map<String, Object> map = Utils.parseParameters(args) ;
+
+ // Run test
+ SupportedQueryTypesTest test = new SupportedQueryTypesTest();
+ test.run(map);
+
+ }
+
+ public void run(Map<String, Object> args) {
+ int errorCount = 0;
+
+ ObjectName on = null;
+ ObjectName serverDelegateObjectName = null;
+
+ JMXConnectorServer cs = null;
+ JMXConnector cc = null;
+
+ System.out.println("SupportedQueryTypesTest::run: Start") ;
+ try {
+ // JMX MbeanServer used inside single VM as if remote.
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+ JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+ cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+ cs.start();
+
+ JMXServiceURL addr = cs.getAddress();
+ cc = JMXConnectorFactory.connect(addr);
+ mbsc = cc.getMBeanServerConnection();
+
+
+ // Create and register the ServerDelegate MBean on the remote MBeanServer
+ String serverDelegateClassName = ServerDelegate.class.getName();
+ serverDelegateObjectName =
+ new ObjectName("defaultDomain:class=" + serverDelegateClassName);
+ mbsc.createMBean(serverDelegateClassName, serverDelegateObjectName);
+
+ // Retrieve the MBean class name
+ mbeanClassName = (String) args.get("-mbeanClassName") ;
+ on = new ObjectName("defaultDomain:class=" + mbeanClassName);
+
+ // Create and register the MBean on the remote MBeanServer
+ System.out.println("SupportedQueryTypesTest::run: CREATE " +
+ mbeanClassName + " on the remote MBeanServer with name "
+ + on);
+ mbsc.createMBean(mbeanClassName, on);
+
+ // Create a QueryFactory and setup which query we'll use.
+ QueryFactory queries = new QueryFactory(mbeanClassName);
+ queries.buildQueries();
+ int maxIndex = queries.getSize();
+ int minIndex = 1;
+
+ // Create a reference Set<ObjectName> to check later on
+ // the queryNames() results
+ Set<ObjectName> referenceNameSet = new HashSet<ObjectName>();
+ referenceNameSet.add(on);
+
+ // Create a reference Set<ObjectInstance> to check later on
+ // the queryMBeans() results
+ ObjectInstance oi = new ObjectInstance(on, mbeanClassName);
+ Set<ObjectInstance> referenceInstanceSet =
+ new HashSet<ObjectInstance>();
+ referenceInstanceSet.add(oi);
+
+ // Perform the queryNames and queryMBeans requests
+ for (int i = minIndex; i <= maxIndex; i++ ) {
+ QueryExp query = queries.getQuery(i);
+ System.out.println("----");
+ System.out.println("SupportedQueryTypesTest::run: Query # " + i);
+ System.out.println("query " + query);
+ errorCount +=
+ doQueryNames(query, referenceNameSet);
+ errorCount +=
+ doQueryMBeans(query, referenceInstanceSet);
+ }
+
+ } catch(Exception e) {
+ Utils.printThrowable(e, true);
+ errorCount++;
+
+ } finally {
+ // Do unregister the MBean
+ try {
+ if (mbsc.isRegistered(on)) {
+ mbsc.unregisterMBean(on);
+ }
+ if (mbsc.isRegistered(serverDelegateObjectName)) {
+ mbsc.unregisterMBean(serverDelegateObjectName);
+ }
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++;
+ }
+
+ try {
+ // Close JMX Connector Client
+ cc.close();
+ // Stop connertor server
+ cs.stop();
+
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++;
+ }
+ }
+
+ System.out.println("");
+ System.out.println("SupportedQueryTypesTest::run: Done") ;
+
+ // Handle result
+ if (errorCount == 0) {
+ System.out.println("SupportedQueryTypesTest::run: (OK)");
+ } else {
+ String message = "SupportedQueryTypesTest::run: (ERROR) Got " +
+ + errorCount + " error(s)";
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ }
+
+
+ private int doQueryNames(QueryExp query, Set<ObjectName> referenceSet) {
+ int errorCount = 0;
+ System.out.println(" <*> Perform queryNames call ");
+
+ try {
+ // Call queryNames on the remote MBeanServer
+ Set<ObjectName> remoteSet = mbsc.queryNames(null, query);
+
+ // Compare the 2 Set<ObjectName>
+ errorCount += checkSet(remoteSet, referenceSet);
+
+ // Cleaning
+ remoteSet.clear();
+
+ } catch (Exception e) {
+ Utils.printThrowable(e, true);
+ errorCount++;
+ }
+
+ if ( errorCount == 0 ) {
+ System.out.println("\t(OK)");
+ } else {
+ System.out.println("\t(ERROR) Query failed");
+ }
+
+ return errorCount;
+ }
+
+
+ private int doQueryMBeans(QueryExp query, Set<ObjectInstance> referenceSet) {
+ int errorCount = 0;
+ System.out.println(" <*> Perform queryMBeans call ");
+
+ try {
+ // Call queryMBeans on the remote MBeanServer
+ Set<ObjectInstance> remoteSet = mbsc.queryMBeans(null, query);
+
+ // Compare the 2 Set<ObjectInstance>
+ errorCount += checkSet(remoteSet, referenceSet);
+
+ // Cleaning
+ remoteSet.clear();
+
+ } catch (Exception e) {
+ Utils.printThrowable(e, true);
+ errorCount++;
+ }
+
+ if ( errorCount == 0 ) {
+ System.out.println("\t(OK)");
+ } else {
+ System.out.println("\t(ERROR) Query failed");
+ }
+
+ return errorCount;
+ }
+
+ /**
+ * Pretty print of a Set content.
+ * When the Set isn't empty, toString() is called on each element.
+ * <br>The variable's name used to hold that Set is given via the setName
+ * parameter and used in the output.
+ */
+ private static void printSet(Set<?> printableSet, String setName) {
+ if ( printableSet.size() == 0 ) {
+ System.out.println("The Set " + setName + " is empty");
+ } else {
+ System.out.println("The Set " + setName + " contains :");
+
+ for (Iterator<?> it = printableSet.iterator(); it.hasNext();) {
+ Object elem = it.next();
+ System.out.println("\t" + elem.toString());
+ }
+ }
+ }
+
+
+ /**
+ * This method check the Set remoteSet is equal to
+ * the reference Set referenceSet,
+ * which means same size and content (order doesn't matter).
+ * <br>It returns 0 when the check is fine, otherwise 1.
+ */
+ private int checkSet(Set<?> remoteSet, Set<?> referenceSet) {
+ if ( ! remoteSet.equals(referenceSet) ) {
+ System.out.println("SupportedQueryTypesTest::checkSet:"
+ + " (ERROR) Set aren't as expected");
+ printSet(remoteSet, "remoteSet");
+ printSet(referenceSet, "referenceSet");
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ // Utility inner class coming from JMX Tonga test suite.
+ private static class Utils {
+
+ // DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property
+ static final String DEBUG_HEADER = "[debug] ";
+
+ // DEBUG levels
+ static int selectedDebugLevel = 0;
+ static final int DEBUG_STANDARD = 1;
+ static final int DEBUG_VERBOSE = 2; // Mainly used for stress tests
+ static final int DEBUG_ALL = DEBUG_STANDARD | DEBUG_VERBOSE;
+
+ static void parseDebugProperties() {
+ int level = 0;
+ Properties p = System.getProperties();
+
+ // get selected levels
+ if (p.getProperty("DEBUG_STANDARD") != null) {
+ level |= DEBUG_STANDARD;
+ }
+
+ if (p.getProperty("DEBUG_VERBOSE") != null) {
+ level |= DEBUG_VERBOSE;
+ }
+
+ if (p.getProperty("DEBUG_ALL") != null) {
+ level |= DEBUG_ALL;
+ }
+
+ selectedDebugLevel = level;
+ }
+
+ /**
+ * Reproduces the original parsing and collection of test parameters
+ * from the DTonga JMX test suite.
+ *
+ * Collects passed args and returns them in a map(argname, value) structure,
+ * which will be then propagated as necessary to various called methods.
+ */
+ static Map<String, Object> parseParameters(String args[])
+ throws Exception {
+ debug(DEBUG_STANDARD, "TestRoot::parseParameters: Start");
+ HashMap<String, Object> map = new HashMap<>();
+
+ for ( int i = 0; i < args.length; i++ ) {
+ if ( args[i].trim().startsWith("-") ) {
+ if ((i+1) < args.length && !args[i+1].startsWith("-") ) {
+ debug(DEBUG_STANDARD,
+ "TestRoot::parseParameters: added in map = " +
+ args[i] +
+ " with value " +
+ args[i+1]) ;
+ map.put(args[i].trim(), args[i+1].trim()) ;
+ } else if ((i+1) < args.length && args[i+1].startsWith("-") ||
+ (i+1) == args.length ) {
+ debug(DEBUG_STANDARD,
+ "TestRoot::parseParameters: added in map = " +
+ args[i] +
+ " with null value") ;
+ map.put(args[i].trim(), null) ;
+ } else {
+ System.out.println(
+ "TestRoot::parseParameters: (WARNING) not added in map = " +
+ args[i]) ;
+ }
+ }
+ }
+
+ debug(DEBUG_STANDARD, "TestRoot::parseParameters: Done") ;
+ return map ;
+ }
+
+ /**
+ * This method is to be used in all tests to print anything
+ * that is temporary.
+ * Printing is done only when debug is activated by the property DEBUG.
+ * Printing depends also on the DEBUG_LEVEL property.
+ * Here it encapsulates a System.out.println.
+ */
+ static void debug(int level, String line) {
+ if ((selectedDebugLevel & level) != 0) {
+ System.out.println(DEBUG_HEADER + line);
+ }
+ }
+
+ /**
+ * Do print stack trace when withStack is true.
+ * Does try to call getTargetException() and getTargetError() then
+ * print embedded stacks in the case of an Exception wrapping
+ * another Exception or an Error. Recurse until no more wrapping
+ * is found.
+ */
+ static void printThrowable(Throwable theThro, boolean withStack) {
+ try {
+ if (withStack) {
+ theThro.printStackTrace(System.out);
+ }
+ if (theThro instanceof Exception) {
+ Exception t = (Exception) theThro;
+ Method target = null;
+ String blank = " ";
+ try {
+ target = t.getClass().getMethod("getTargetException",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetException method could be there or not
+ }
+ System.out.println(blank + t.getClass() + "==>" + t.getMessage());
+ while (target != null) {
+ try {
+ t = (Exception) target.invoke(t,
+ (java.lang.Object[]) null);
+ } catch (Exception ee) {
+ t = null;
+ }
+ try {
+ if (t != null) {
+ blank = blank + " ";
+ System.out.println(blank + t.getClass() + "==>" +
+ t.getMessage());
+ try {
+ target =
+ t.getClass().getMethod("getTargetException",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetException method could be there or not }
+ }
+ } else {
+ target = null;
+ }
+ } catch (Exception ee) {
+ target = null;
+ }
+ }
+
+ // We may have exceptions wrapping an Error then it is
+ // getTargetError that is likely to be called
+ try {
+ target = ((Exception) theThro).getClass().getMethod("getTargetError",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetError method could be there or not
+ }
+ Throwable err = theThro;
+ while (target != null) {
+ try {
+ err = (Error) target.invoke(err,
+ (java.lang.Object[]) null);
+ } catch (Exception ee) {
+ err = null;
+ }
+ try {
+ if (err != null) {
+ blank = blank + " ";
+ System.out.println(blank + err.getClass() + "==>" +
+ err.getMessage());
+ if (withStack) {
+ err.printStackTrace(System.out);
+ }
+ try {
+ target = err.getClass().getMethod("getTargetError",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetError method could be there or not
+ }
+ } else {
+ target = null;
+ }
+ } catch (Exception ee) {
+ target = null;
+ }
+ }
+ } else {
+ System.out.println("Throwable is : " + theThro);
+ }
+ } catch (Throwable x) {
+ System.out.println("Exception : raised in printException : " + x);
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/query/TestQuery.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Class TestQuery
+ * MBean used for testing the types wired when using QueryExp.
+ * It is heavily linked to QueryFactory.
+ */
+public class TestQuery extends QueryData implements TestQueryMBean {
+
+ /**
+ * Attribute : BooleanAtt
+ */
+ private boolean booleanAtt = booleanValue;
+
+ /**
+ * Attribute : DoubleAtt
+ */
+ private double doubleAtt = doubleValue;
+
+ /**
+ * Attribute : FloatAtt
+ */
+ private float floatAtt = floatValue;
+
+ /**
+ * Attribute : IntAtt
+ */
+ private int intAtt = intValue;
+
+ /**
+ * Attribute : IntegerAtt
+ */
+ private Integer integerAtt = integerValue;
+
+ /**
+ * Attribute : LongAtt
+ */
+ private long longAtt = longValue;
+
+ /**
+ * Attribute : StringAtt
+ */
+ private String stringAtt = stringValue;
+
+ public TestQuery() {
+ }
+
+ /**
+ * Get Att of type boolean
+ */
+ public boolean getBooleanAtt() {
+ return booleanAtt;
+ }
+
+ /**
+ * Set Att of type boolean
+ */
+ public void setBooleanAtt(boolean value) {
+ booleanAtt = value;
+ }
+
+ /**
+ * Get Att of type double
+ */
+ public double getDoubleAtt() {
+ return doubleAtt;
+ }
+
+ /**
+ * Set Att of type double
+ */
+ public void setDoubleAtt(double value) {
+ doubleAtt = value;
+ }
+
+ /**
+ * Get Att of type float
+ */
+ public float getFloatAtt() {
+ return floatAtt;
+ }
+
+ /**
+ * Set Att of type float
+ */
+ public void setFloatAtt(float value) {
+ floatAtt = value;
+ }
+
+ /**
+ * Get Att of type int
+ */
+ public int getIntAtt() {
+ return intAtt;
+ }
+
+ /**
+ * Set Att of type int
+ */
+ public void setIntAtt(int value) {
+ intAtt = value;
+ }
+
+ /**
+ * Get Att of type Integer
+ */
+ public Integer getIntegerAtt() {
+ return integerAtt;
+ }
+
+ /**
+ * Set Att of type Integer
+ */
+ public void setIntegerAtt(Integer value) {
+ integerAtt = value;
+ }
+
+ /**
+ * Get Att of type long
+ */
+ public long getLongAtt() {
+ return longAtt;
+ }
+
+ /**
+ * Set Att of type long
+ */
+ public void setLongAtt(long value) {
+ longAtt = value;
+ }
+
+ /**
+ * Get Att of type String
+ */
+ public String getStringAtt() {
+ return stringAtt;
+ }
+
+ /**
+ * Set Att of type String
+ */
+ public void setStringAtt(String value) {
+ stringAtt = value;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/query/TestQueryMBean.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/**
+ * Interface TestQueryMBean
+ * MBean used for testing the types wired when using QueryExp.
+ * It is heavily linked to QueryFactory.
+ */
+public interface TestQueryMBean
+{
+ /**
+ * Get Att of type boolean
+ */
+ public boolean getBooleanAtt();
+
+ /**
+ * Set Att of type boolean
+ */
+ public void setBooleanAtt(boolean value);
+
+ /**
+ * Get Att of type double
+ */
+ public double getDoubleAtt();
+
+ /**
+ * Set Att of type double
+ */
+ public void setDoubleAtt(double value);
+
+ /**
+ * Get Att of type float
+ */
+ public float getFloatAtt();
+
+ /**
+ * Set Att of type float
+ */
+ public void setFloatAtt(float value);
+
+ /**
+ * Get Att of type int
+ */
+ public int getIntAtt();
+
+ /**
+ * Set Att of type int
+ */
+ public void setIntAtt(int value);
+
+ /**
+ * Get Att of type Integer
+ */
+ public Integer getIntegerAtt();
+
+ /**
+ * Set Att of type Integer
+ */
+ public void setIntegerAtt(Integer value);
+
+ /**
+ * Get Att of type long
+ */
+ public long getLongAtt();
+
+ /**
+ * Set Att of type long
+ */
+ public void setLongAtt(long value);
+
+ /**
+ * Get Att of type String
+ */
+ public String getStringAtt();
+
+ /**
+ * Set Att of type String
+ */
+ public void setStringAtt(String value);
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/security/AuthorizationTest.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,613 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8058865
+ * @summary Checks various authentication behavior from remote jmx client
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @compile Simple.java
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username2 -Dpassword=password2 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedSetException -expectedInvokeException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username6 -Dpassword=password6 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username3 -Dpassword=password3 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials -expectedGetException
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username5 -Dpassword=password5 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username6 -Dpassword=password6 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username2 -Dpassword=password2 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedSetException -expectedInvokeException
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username3 -Dpassword=password3 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username4 -Dpassword=password4 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedGetException -expectedSetException
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username5 -Dpassword=password5 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
+ */
+
+import java.io.File;
+import java.util.Map ;
+import java.util.HashMap ;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import java.lang.management.ManagementFactory;
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory ;
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+import javax.management.Attribute ;
+import javax.management.ObjectName ;
+
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JDKToolFinder;
+
+public class AuthorizationTest {
+
+ static final String SERVER_CLASS_NAME = "AuthorizationTest";
+ static final String CLIENT_CLASS_NAME = "AuthorizationTest$ClientSide";
+ static final String CLIENT_CLASS_MAIN = CLIENT_CLASS_NAME;
+
+ static final String USERNAME_PROPERTY = "username";
+ static final String PASSWORD_PROPERTY = "password";
+
+ private JMXConnectorServer cs;
+
+ /*
+ * First Debug properties and arguments are collect in expected
+ * map (argName, value) format, then calls original test's run method.
+ */
+ public static void main(String args[]) throws Exception {
+
+ System.out.println("=================================================");
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+
+ // Supported parameters list format is :
+ // "MainClass [-server <param-spec> ...] [-client <param-spec> ...]
+ // with <param-spec> either "-parami valuei" or "-parami"
+ HashMap<String, Object> serverMap = new HashMap<>() ;
+ int clientArgsIndex =
+ Utils.parseServerParameters(args, SERVER_CLASS_NAME, serverMap);
+
+ // Extract and records client params
+ String[] clientParams = null;
+ if (clientArgsIndex < args.length) {
+ int clientParamsSize = args.length - clientArgsIndex;
+ clientParams = new String[clientParamsSize];
+ System.arraycopy(args, clientArgsIndex, clientParams, 0, clientParamsSize);
+ } else {
+ clientParams = new String[0];
+ }
+
+ // Run test
+ AuthorizationTest test = new AuthorizationTest();
+ test.run(serverMap, clientParams);
+
+ }
+
+ /*
+ * Create the MBeansServer side of the test and returns its address
+ */
+ private JMXServiceURL createServerSide(Map<String, Object> serverMap)
+ throws Exception {
+ final int NINETY_SECONDS = 90;
+
+ System.out.println("AuthorizationTest::createServerSide: Start") ;
+
+ MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+ JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+
+ // Creates connection environment from server side params
+ HashMap<String, Object> env = new HashMap<>();
+ String value = null;
+
+ if ((value = (String)serverMap.get("-mapType")) != null) {
+ if (value.contains("x.access.file")) {
+ String accessFileStr = System.getProperty("test.src") +
+ File.separator + "access.properties";
+ env.put("jmx.remote.x.access.file", accessFileStr);
+ System.out.println("Added " + accessFileStr + " file as jmx.remote.x.access.file");
+ }
+ if (value.contains("x.password.file")) {
+ String passwordFileStr = System.getProperty("test.src") +
+ File.separator + "password.properties";
+ env.put("jmx.remote.x.password.file", passwordFileStr);
+ System.out.println("Added " + passwordFileStr + " file as jmx.remote.x.password.file");
+ }
+ }
+
+ if (serverMap.containsKey("-populate")) {
+ String populateClassName = "Simple";
+ ObjectName on =
+ new ObjectName("defaultDomain:class=Simple");
+
+ Utils.debug(Utils.DEBUG_STANDARD, "create and register Simple MBean") ;
+ mbs.createMBean(populateClassName, on);
+ }
+
+ cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
+ cs.start();
+
+ Utils.waitReady(cs, NINETY_SECONDS);
+
+ JMXServiceURL addr = cs.getAddress();
+
+ System.out.println("AuthorizationTest::createServerSide: Done.") ;
+
+ return addr;
+ }
+
+ /*
+ * Creating command-line for running subprocess JVM:
+ *
+ * JVM command line is like:
+ * {test_jdk}/bin/java {defaultopts} -cp {test.class.path} {testopts} main
+ *
+ * {defaultopts} are the default java options set by the framework.
+ *
+ */
+ private List<String> buildCommandLine(String args[]) {
+ List<String> opts = new ArrayList<>();
+ opts.add(JDKToolFinder.getJDKTool("java"));
+ opts.addAll(Arrays.asList(jdk.testlibrary.Utils.getTestJavaOpts()));
+
+ String usernameValue = System.getProperty(USERNAME_PROPERTY);
+ if (usernameValue != null) {
+ opts.add("-D" + USERNAME_PROPERTY + "=" + usernameValue);
+ }
+ String passwordValue = System.getProperty(PASSWORD_PROPERTY);
+ if (passwordValue != null) {
+ opts.add("-D" + PASSWORD_PROPERTY + "=" + passwordValue);
+ }
+
+ opts.add("-cp");
+ opts.add(System.getProperty("test.class.path", "test.class.path"));
+ opts.add(CLIENT_CLASS_MAIN);
+ opts.addAll(Arrays.asList(args));
+ return opts;
+ }
+
+ /**
+ * Runs AuthorizationTest$ClientSide with the passed options and redirects
+ * subprocess standard I/O to the current (parent) process. This provides a
+ * trace of what happens in the subprocess while it is runnning (and before
+ * it terminates).
+ *
+ * @param serviceUrlStr string representing the JMX service Url to connect to.
+ */
+ private int runClientSide(String args[], String serviceUrlStr) throws Exception {
+
+ // Building command-line
+ List<String> opts = buildCommandLine(args);
+ opts.add("-serviceUrl");
+ opts.add(serviceUrlStr);
+
+ // Launch separate JVM subprocess
+ int exitCode = 0;
+ String[] optsArray = opts.toArray(new String[0]);
+ ProcessBuilder pb = new ProcessBuilder(optsArray);
+ Process p = ProcessTools.startProcess("AuthorizationTest$ClientSide", pb);
+
+ // Handling end of subprocess
+ try {
+ exitCode = p.waitFor();
+ if (exitCode != 0) {
+ System.out.println(
+ "Subprocess unexpected exit value of [" + exitCode +
+ "]. Expected 0.\n");
+ }
+ } catch (InterruptedException e) {
+ System.out.println("Parent process interrupted with exception : \n " + e + " :" );
+
+ // Parent thread unknown state, killing subprocess.
+ p.destroyForcibly();
+
+ throw new RuntimeException(
+ "Parent process interrupted with exception : \n " + e + " :" );
+
+ } finally {
+ if (p.isAlive()) {
+ p.destroyForcibly();
+ }
+ return exitCode;
+ }
+
+ }
+
+ public void run(Map<String, Object> serverArgs, String clientArgs[]) {
+
+ System.out.println("AuthorizationTest::run: Start") ;
+ int errorCount = 0;
+
+ try {
+ // Initialise the server side
+ JMXServiceURL urlToUse = createServerSide(serverArgs);
+
+ // Run client side
+ errorCount = runClientSide(clientArgs, urlToUse.toString());
+
+ if ( errorCount == 0 ) {
+ System.out.println("AuthorizationTest::run: Done without any error") ;
+ } else {
+ System.out.println("AuthorizationTest::run: Done with "
+ + errorCount
+ + " error(s)") ;
+ throw new RuntimeException("errorCount = " + errorCount);
+ }
+
+ cs.stop();
+
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ private static class ClientSide {
+
+ private JMXConnector cc = null;
+ private MBeanServerConnection mbsc = null;
+
+ public static void main(String args[]) throws Exception {
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+
+ // Supported parameters list format is : "MainClass [-client <param-spec> ...]
+ // with <param-spec> either "-parami valuei" or "-parami"
+ HashMap<String, Object> clientMap = new HashMap<>() ;
+ Utils.parseClientParameters(args, CLIENT_CLASS_NAME, clientMap);
+
+ // Run test
+ ClientSide test = new ClientSide();
+ test.run(clientMap);
+
+ }
+
+ public void run(Map<String, Object> args) {
+
+ int errorCount = 0 ;
+
+ try {
+ boolean expectedCreateException =
+ (args.containsKey("-expectedCreateException")) ? true : false ;
+ boolean expectedGetException =
+ (args.containsKey("-expectedGetException")) ? true : false ;
+ boolean expectedSetException =
+ (args.containsKey("-expectedSetException")) ? true : false ;
+ boolean expectedInvokeException =
+ (args.containsKey("-expectedInvokeException")) ? true : false ;
+ // JSR262 (see bug 6440374)
+ // There is no special JSR262 protocol operation for connect.
+ // The first request sent initiate the connection.
+ // In the JSR262 current implementation, getDefaultDomain is sent to
+ // the server in order to get the server part of the connection ID.
+ // => the connection may fail if no access permission on get requests.
+ boolean expectedConnectException =
+ (args.containsKey("-expectedConnectException")) ? true : false ;
+ // Before connection,
+ // remove the element of the Map with null values (not supported by RMI)
+ // See bug 4982668
+ args.remove("-expectedCreateException");
+ args.remove("-expectedGetException");
+ args.remove("-expectedSetException");
+ args.remove("-expectedInvokeException");
+ args.remove("-expectedConnectException");
+
+
+ // Here do connect to the JMX Server
+ String username = System.getProperty("username");
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::run: CONNECT on behalf of \"" + username + "\"");
+ doConnect(args, expectedConnectException);
+
+ // If the connection did not fail, perform some requests.
+ // At this stage the mbeanserver connection is up and running
+ if (mbsc != null) {
+ ObjectName on = new ObjectName("defaultDomain:class=Simple");
+
+ // Create request
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::run: CREATE on behalf of \"" +
+ username + "\"");
+ errorCount += doCreateRequest(mbsc,
+ new ObjectName("defaultDomain:class=Simple,user=" + username),
+ expectedCreateException);
+
+ // Get request
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::run: GET on behalf of \"" +
+ username + "\"");
+ errorCount += doGetRequest(mbsc, on, expectedGetException);
+
+ // Set request
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::run: SET on behalf of \"" +
+ username + "\"");
+ errorCount += doSetRequest(mbsc, on, expectedSetException);
+
+ // Invoke request
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::run: INVOKE on behalf of \"" +
+ username + "\"");
+ errorCount += doInvokeRequest(mbsc, on, expectedInvokeException);
+ }
+
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++;
+ } finally {
+ // Terminate the JMX Client
+ try {
+ cc.close();
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++;
+ }
+ }
+
+ System.out.println("ClientSide::run: Done") ;
+
+ // Handle result
+ if (errorCount == 0) {
+ System.out.println("ClientSide::run: (OK) authorization test succeeded.");
+ } else {
+ String message = "AuthorizationTest$ClientSide::run: (ERROR) " +
+ " authorization test failed with " +
+ errorCount + " error(s)";
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ }
+
+ protected void doConnect(Map<String, Object> args,
+ boolean expectedException) {
+
+ String msgTag = "ClientSide::doConnect";
+ boolean throwRuntimeException = false;
+ String message = "";
+
+ try {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::doConnect: Connect the client");
+
+ // Collect connection environment
+ HashMap<String, Object> env = new HashMap<>();
+
+ Object value = args.get("-mapType");
+ if (value != null) {
+ String username = System.getProperty("username");
+ String password = System.getProperty("password");
+ Utils.debug(Utils.DEBUG_STANDARD,
+ msgTag + "add \"jmx.remote.credentials\" = \"" +
+ username + "\", \"" + password + "\"");
+ env.put("jmx.remote.credentials",
+ new String[] { username , password });
+ }
+
+ // Get a connection to remote mbean server
+ JMXServiceURL addr = new JMXServiceURL((String)args.get("-serviceUrl"));
+ cc = JMXConnectorFactory.connect(addr,env);
+ mbsc = cc.getMBeanServerConnection();
+
+ if (expectedException) {
+ message = "ClientSide::doConnect: (ERROR) " +
+ "Connect did not fail with expected SecurityException";
+ System.out.println(message);
+ throwRuntimeException = true;
+ } else {
+ System.out.println("ClientSide::doConnect: (OK) Connect succeed");
+ }
+ } catch(Exception e) {
+ Utils.printThrowable(e, true);
+ if (expectedException) {
+ if (e instanceof java.lang.SecurityException) {
+ System.out.println("ClientSide::doConnect: (OK) " +
+ "Connect failed with expected SecurityException");
+ } else {
+ message = "ClientSide::doConnect: (ERROR) " +
+ "Create failed with " + e.getClass() +
+ " instead of expected SecurityException";
+ System.out.println(message);
+ throwRuntimeException = true;
+ }
+ } else {
+ message = "ClientSide::doConnect: (ERROR) " +
+ "Connect failed";
+ System.out.println(message);
+ throwRuntimeException = true;
+ }
+ }
+
+ // If the connection failed, or if the connection succeeded but should not,
+ // no need to go further => throw RuntimeException and exit the test
+ if (throwRuntimeException) {
+ throw new RuntimeException(message);
+ }
+ }
+
+ protected int doCreateRequest(MBeanServerConnection mbsc,
+ ObjectName on,
+ boolean expectedException) {
+ int errorCount = 0;
+
+ try {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::doCreateRequest: Create and register the MBean") ;
+
+ mbsc.createMBean("Simple", on) ;
+
+ if (expectedException) {
+ System.out.println("ClientSide::doCreateRequest: " +
+ "(ERROR) Create did not fail with expected SecurityException");
+ errorCount++;
+ } else {
+ System.out.println("ClientSide::doCreateRequest: (OK) Create succeed") ;
+ }
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ if (expectedException) {
+ if (e instanceof java.lang.SecurityException) {
+ System.out.println("ClientSide::doCreateRequest: " +
+ "(OK) Create failed with expected SecurityException") ;
+ } else {
+ System.out.println("ClientSide::doCreateRequest: " +
+ "(ERROR) Create failed with " +
+ e.getClass() + " instead of expected SecurityException");
+ errorCount++;
+ }
+ } else {
+ System.out.println("ClientSide::doCreateRequest: " +
+ "(ERROR) Create failed");
+ errorCount++;
+ }
+ }
+ return errorCount;
+ }
+
+ protected int doGetRequest(MBeanServerConnection mbsc,
+ ObjectName on,
+ boolean expectedException) {
+ int errorCount = 0;
+
+ try {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::doGetRequest: Get attributes of the MBean") ;
+
+ mbsc.getAttribute(on, "Attribute");
+
+ if (expectedException) {
+ System.out.println("ClientSide::doGetRequest: " +
+ "(ERROR) Get did not fail with expected SecurityException");
+ errorCount++;
+ } else {
+ System.out.println("ClientSide::doGetRequest: (OK) Get succeed") ;
+ }
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ if (expectedException) {
+ if (e instanceof java.lang.SecurityException) {
+ System.out.println("ClientSide::doGetRequest: " +
+ "(OK) Get failed with expected SecurityException") ;
+ } else {
+ System.out.println("ClientSide::doGetRequest: " +
+ "(ERROR) Get failed with " +
+ e.getClass() + " instead of expected SecurityException");
+ errorCount++;
+ }
+ } else {
+ System.out.println("ClientSide::doGetRequest: (ERROR) Get failed");
+ errorCount++;
+ }
+ }
+
+ return errorCount;
+ }
+
+ protected int doSetRequest(MBeanServerConnection mbsc,
+ ObjectName on,
+ boolean expectedException) {
+ int errorCount = 0;
+
+ try {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::doSetRequest: Set attributes of the MBean") ;
+
+ Attribute attribute = new Attribute("Attribute", "My value") ;
+ mbsc.setAttribute(on, attribute) ;
+
+ if (expectedException) {
+ System.out.println("ClientSide::doSetRequest: " +
+ "(ERROR) Set did not fail with expected SecurityException");
+ errorCount++;
+ } else {
+ System.out.println("ClientSide::doSetRequest: (OK) Set succeed") ;
+ }
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ if (expectedException) {
+ if (e instanceof java.lang.SecurityException) {
+ System.out.println("ClientSide::doSetRequest: " +
+ "(OK) Set failed with expected SecurityException") ;
+ } else {
+ System.out.println("ClientSide::doSetRequest: " +
+ "(ERROR) Set failed with " +
+ e.getClass() + " instead of expected SecurityException");
+ errorCount++;
+ }
+ } else {
+ System.out.println("ClientSide::doSetRequest: (ERROR) Set failed");
+ errorCount++;
+ }
+ }
+ return errorCount;
+ }
+
+ protected int doInvokeRequest(MBeanServerConnection mbsc,
+ ObjectName on,
+ boolean expectedException) {
+ int errorCount = 0;
+
+ try {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::doInvokeRequest: Invoke operations on the MBean") ;
+
+ mbsc.invoke(on, "operation", null, null) ;
+
+ if (expectedException) {
+ System.out.println("ClientSide::doInvokeRequest: " +
+ "(ERROR) Invoke did not fail with expected SecurityException");
+ errorCount++;
+ } else {
+ System.out.println("ClientSide::doInvokeRequest: (OK) Invoke succeed") ;
+ }
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ if (expectedException) {
+ if (e instanceof java.lang.SecurityException) {
+ System.out.println("ClientSide::doInvokeRequest: " +
+ "(OK) Invoke failed with expected SecurityException") ;
+ } else {
+ System.out.println("ClientSide::doInvokeRequest: " +
+ " (ERROR) Invoke failed with " +
+ e.getClass() + " instead of expected SecurityException");
+ errorCount++;
+ }
+ } else {
+ System.out.println("ClientSide::doInvokeRequest: " +
+ "(ERROR) Invoke failed");
+ errorCount++;
+ }
+ }
+ return errorCount;
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/security/MBS_Light.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import javax.security.auth.Subject;
+import java.security.Principal;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.management.MBeanRegistration ;
+import javax.management.MBeanServer ;
+import javax.management.ObjectName ;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationListener;
+import javax.management.Notification;
+
+public class MBS_Light extends NotificationBroadcasterSupport
+ implements MBS_LightMBean, MBeanRegistration, NotificationListener
+{
+ private RjmxMBeanParameter param = null ;
+ private String aString = "notset" ;
+ private int anInt = 0 ;
+ private MBeanServer mbs = null ;
+ private ObjectName objname = null ;
+ private Exception anException = null ;
+ private Error anError = null ;
+ private int count = 0;
+ private SimpleListener listener = new SimpleListener();
+
+ @SqeDescriptorKey("NO PARAMETER CONSTRUCTOR MBS_Light")
+ public MBS_Light() {
+ }
+
+ @SqeDescriptorKey("ONE RjmxMBeanParameter PARAMETER CONSTRUCTOR MBS_Light")
+ public MBS_Light(@SqeDescriptorKey("CONSTRUCTOR PARAMETER param")
+ RjmxMBeanParameter param) {
+ this.param = param ;
+ }
+
+ @SqeDescriptorKey("ONE String PARAMETER CONSTRUCTOR MBS_Light")
+ public MBS_Light(@SqeDescriptorKey("CONSTRUCTOR PARAMETER param")String param) {
+ this.aString = param ;
+ }
+
+ // Getter for property param
+ public RjmxMBeanParameter getParam() {
+ return this.param ;
+ }
+
+ // Setter for property param
+ public void setParam(RjmxMBeanParameter param) {
+ this.param = param ;
+ }
+
+ // Getter for property aString
+ public String getAstring() {
+ return this.aString ;
+ }
+
+ // Setter for property aString
+ public void setAstring(String aString) {
+ this.aString = aString ;
+ }
+
+ // Getter for property anInt
+ public int getAnInt() {
+ return this.anInt ;
+ }
+
+ // Setter for property anInt
+ public void setAnInt(int anInt) {
+ this.anInt = anInt ;
+ }
+
+ // Getter for property anException
+ public Exception getAnException() {
+ return this.anException ;
+ }
+
+ // Setter for property anException
+ public void setAnException(Exception anException) {
+ this.anException = anException ;
+ }
+
+ // Getter for property anError
+ public Error getAnError() {
+ return this.anError ;
+ }
+
+ // Setter for property anError
+ public void setAnError(Error anError) {
+ this.anError = anError ;
+ }
+
+ // An operation
+ public RjmxMBeanParameter operate1(String name) {
+ return new RjmxMBeanParameter(name) ;
+ }
+
+ // An operation
+ public String operate2(RjmxMBeanParameter param) {
+ return param.name ;
+ }
+
+ // An operation
+ public void throwError() {
+ throw new Error("JSR-160-ERROR");
+ }
+
+ // An operation
+ public void throwException() throws Exception {
+ throw new Exception("JSR-160-EXCEPTION");
+ }
+
+ // MBeanRegistration method
+ public void postDeregister() {
+ }
+
+ // MBeanRegistration method
+ public void postRegister(Boolean registrationDone) {
+ }
+
+ // MBeanRegistration method
+ public void preDeregister()
+ throws Exception
+ {
+ }
+
+ // MBeanRegistration method
+ public ObjectName preRegister(MBeanServer server, ObjectName name)
+ throws Exception
+ {
+ this.mbs = server ;
+ if ( name == null ) {
+ this.objname = new ObjectName("protocol:class=MBS_Light") ;
+ }
+ else {
+ this.objname = name ;
+ }
+ return this.objname ;
+ }
+
+ public synchronized void handleNotification(Notification notification,
+ Object handback) {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "MBS_Light::handleNotification: " + notification);
+ listener.handleNotification(notification, handback);
+ }
+
+ // Send a notification
+ public void sendNotification() {
+ Notification notification =
+ new Notification("JSR160-TCK-NOTIFICATION", this, count++);
+ sendNotification(notification);
+ }
+
+ public Object waitForNotificationHB() {
+ return listener.waitForNotificationHB();
+ }
+
+ // Receive multi notifications and send back handbacks
+ public synchronized Object[] waitForMultiNotifications(String nb) {
+ return listener.waitForMultiNotifications(Integer.valueOf(nb).intValue());
+ }
+
+ // Receive a notification
+ public synchronized String waitForNotification() {
+ return listener.waitForNotification();
+ }
+
+ // Is the notification received
+ public synchronized Boolean notificationReceived() {
+ return Boolean.valueOf(listener.isNotificationReceived());
+ }
+
+ // The authorization Id
+ public String getAuthorizationId() {
+ AccessControlContext acc = AccessController.getContext();
+ Subject subject = Subject.getSubject(acc);
+ Set<Principal> principals = subject.getPrincipals();
+ Iterator<Principal> i = principals.iterator();
+ StringBuffer buffer = new StringBuffer();
+ while(i.hasNext()) {
+ Principal p = i.next();
+ buffer.append(p.getName());
+ if(i.hasNext())
+ buffer.append(" ");
+ }
+
+ return buffer.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/security/MBS_LightMBean.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+@SqeDescriptorKey("INTERFACE MBS_LightMBean")
+public interface MBS_LightMBean {
+ // Getter for property param
+ @SqeDescriptorKey("ATTRIBUTE Param")
+ public RjmxMBeanParameter getParam() ;
+
+ // Setter for property param
+ @SqeDescriptorKey("ATTRIBUTE Param")
+ public void setParam(RjmxMBeanParameter param) ;
+
+ // Getter for property aString
+ @SqeDescriptorKey("ATTRIBUTE Astring")
+ public String getAstring() ;
+
+ // Setter for property aString
+ @SqeDescriptorKey("ATTRIBUTE Astring")
+ public void setAstring(String aString) ;
+
+ // Getter for property anInt
+ @SqeDescriptorKey("ATTRIBUTE AnInt")
+ public int getAnInt() ;
+
+ // Setter for property anInt
+ @SqeDescriptorKey("ATTRIBUTE AnInt")
+ public void setAnInt(int anInt) ;
+
+ // Getter for property anException
+ @SqeDescriptorKey("ATTRIBUTE AnException")
+ public Exception getAnException() ;
+
+ // Setter for property anException
+ @SqeDescriptorKey("ATTRIBUTE AnException")
+ public void setAnException(Exception anException) ;
+
+ // Getter for property anError
+ @SqeDescriptorKey("ATTRIBUTE AnError")
+ public Error getAnError() ;
+
+ // Setter for property anError
+ @SqeDescriptorKey("ATTRIBUTE AnError")
+ public void setAnError(Error anError) ;
+
+ // An operation
+ @SqeDescriptorKey("OPERATION operate1")
+ public RjmxMBeanParameter operate1(
+ @SqeDescriptorKey("OPERATION PARAMETER name")String name) ;
+
+ // An operation
+ @SqeDescriptorKey("OPERATION operate2")
+ public String operate2(
+ @SqeDescriptorKey("OPERATION PARAMETER param")RjmxMBeanParameter param) ;
+
+ // Throws an error
+ @SqeDescriptorKey("OPERATION throwError")
+ public void throwError();
+
+ // Throws an exception
+ @SqeDescriptorKey("OPERATION throwException")
+ public void throwException() throws Exception;
+
+ // Send a notification
+ @SqeDescriptorKey("OPERATION sendNotification")
+ public void sendNotification();
+
+ // Receive a notification and return the type
+ @SqeDescriptorKey("OPERATION waitForNotification")
+ public String waitForNotification();
+
+ // Receive a notification and return the HandBack
+ @SqeDescriptorKey("OPERATION waitForNotificationHB")
+ public Object waitForNotificationHB();
+
+ // Receive multi notifications and return the HandBacks
+ @SqeDescriptorKey("OPERATION waitForMultiNotifications")
+ public Object[] waitForMultiNotifications(
+ @SqeDescriptorKey("OPERATION PARAMETER nb")String nb);
+
+ // Is the notification received
+ @SqeDescriptorKey("OPERATION notificationReceived")
+ public Boolean notificationReceived();
+
+ // Return the current authorization Id
+ @SqeDescriptorKey("OPERATION getAuthorizationId")
+ public String getAuthorizationId();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/security/RjmxMBeanParameter.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.Serializable ;
+
+/**
+ * That class is used to modelize a parameter to be used as MBean property
+ * value or MBean operation parameter or returned value.
+ */
+public class RjmxMBeanParameter implements Serializable {
+ public String name = "unset" ;
+
+ public RjmxMBeanParameter() {
+ }
+
+ public RjmxMBeanParameter(String name) {
+ this.name = name ;
+ }
+
+ public boolean equals(Object obj) {
+ if ( this.name.equals(((RjmxMBeanParameter)obj).name) ) {
+ return true ;
+ } else {
+ return false ;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/security/SecurityTest.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,800 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8058865
+ * @summary Checks various secure ways of connecting from remote jmx client
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @compile MBS_Light.java ServerDelegate.java TestSampleLoginModule.java
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=SQE_username -Dpassword=SQE_password SecurityTest -server -mapType x.password.file -client -mapType credentials
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=UNKNOWN_username -Dpassword=SQE_password SecurityTest -server -mapType x.password.file -client -mapType credentials -expectedThrowable java.lang.SecurityException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=SQE_username -Dpassword=WRONG_password SecurityTest -server -mapType x.password.file -client -mapType credentials -expectedThrowable java.lang.SecurityException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dsusername=TestJMXAuthenticatorUsername -Dspassword=TestJMXAuthenticatorPassword -Dusername=TestJMXAuthenticatorUsername -Dpassword=TestJMXAuthenticatorPassword SecurityTest -server -mapType x.authenticator -client -mapType credentials
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dsusername=TestJMXAuthenticatorUsername -Dspassword=TestJMXAuthenticatorPassword -Dusername=AnotherTestJMXAuthenticatorUsername -Dpassword=TestJMXAuthenticatorPassword SecurityTest -server -mapType x.authenticator -client -mapType credentials -expectedThrowable java.lang.SecurityException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config -Dpassword.file=password.properties -Dusername=usernameFileLoginModule -Dpassword=passwordFileLoginModule SecurityTest -server -mapType x.login.config.PasswordFileAuthentication -client -mapType credentials
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config.UNKNOWN -Dpassword.file=password.properties -Dusername=usernameFileLoginModule -Dpassword=passwordFileLoginModule SecurityTest -server -mapType x.login.config.PasswordFileAuthentication -client -mapType credentialss -expectedThrowable java.lang.SecurityException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config -Dpassword.file=password.properties -Dusername=usernameFileLoginModule -Dpassword=passwordFileLoginModule SecurityTest -server -mapType x.login.config.UnknownAuthentication -client -mapType credentials -expectedThrowable java.lang.SecurityException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config -Dsusername=usernameSampleLoginModule -Dspassword=passwordSampleLoginModule -Dpassword.file=password.properties -Dusername=usernameSampleLoginModule -Dpassword=passwordSampleLoginModule SecurityTest -server -mapType x.login.config.SampleLoginModule -client -mapType credentials
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config -Dsusername=usernameSampleLoginModule -Dspassword=passwordSampleLoginModule -Dpassword.file=password.properties -Dusername=AnotherUsernameSampleLoginModule -Dpassword=passwordSampleLoginModule SecurityTest -server -mapType x.login.config.SampleLoginModule -client -mapType credentials -expectedThrowable java.lang.SecurityException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword WRONG_password -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.server.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.need.client.authentication -keystore keystoreAgent -keystorepassword glopglop -truststore truststoreAgent -truststorepassword glopglop -client -keystore keystoreClient -keystorepassword glopglop -truststore truststoreClient -truststorepassword glopglop
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.need.client.authentication -keystore keystoreAgent -keystorepassword glopglop -truststore truststoreAgent -truststorepassword glopglop -client -keystore keystoreClient -keystorepassword WRONG_password -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.need.client.authentication -keystore keystoreAgent -keystorepassword glopglop -truststore truststoreAgent -truststorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.need.client.authentication -keystore keystoreAgent -keystorepassword glopglop -client -keystore keystoreClient -keystorepassword glopglop -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledCipherSuites=SSL_RSA_WITH_RC4_128_MD5 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.cipher.suites.md5 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledCipherSuites=SSL_RSA_WITH_RC4_128_SHA SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.cipher.suites.md5 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledCipherSuites=SSL_RSA_WITH_RC4_128_MD5 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.cipher.suites.sha -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledProtocols=SSLv3 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.protocols.sslv3 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledProtocols=TLSv1 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.protocols.sslv3 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledProtocols=SSLv3 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.protocols.tlsv1 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ */
+
+import java.io.File;
+import java.util.Map ;
+import java.util.HashMap ;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory ;
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+import javax.management.Attribute ;
+import javax.management.ObjectName ;
+
+import javax.rmi.ssl.SslRMIClientSocketFactory;
+import javax.rmi.ssl.SslRMIServerSocketFactory;
+
+import java.security.Security;
+
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JDKToolFinder;
+
+public class SecurityTest {
+
+ static final String SERVER_CLASS_NAME = "SecurityTest";
+ static final String CLIENT_CLASS_NAME = "SecurityTest$ClientSide";
+ static final String CLIENT_CLASS_MAIN = CLIENT_CLASS_NAME;
+
+ static final String USERNAME_PROPERTY = "username";
+ static final String PASSWORD_PROPERTY = "password";
+
+ static final String SERVER_DELEGATE_MBEAN_NAME =
+ "defaultDomain:class=ServerDelegate";
+
+ static final String RMI_SERVER_SOCKET_FACTORY_SSL = "rmi.server.socket.factory.ssl";
+ static final String RMI_CLIENT_SOCKET_FACTORY_SSL = "rmi.client.socket.factory.ssl";
+ static final String KEYSTORE_PROPNAME = "javax.net.ssl.keyStore";
+ static final String KEYSTORE_PWD_PROPNAME = "javax.net.ssl.keyStorePassword";
+ static final String TRUSTSTORE_PROPNAME = "javax.net.ssl.trustStore";
+ static final String TRUSTSTORE_PWD_PROPNAME = "javax.net.ssl.trustStorePassword";
+
+ static final String RMI_SSL_CLIENT_ENABLEDCIPHERSUITES =
+ "javax.rmi.ssl.client.enabledCipherSuites";
+ static final String RMI_SSL_CLIENT_ENABLEDPROTOCOLS =
+ "javax.rmi.ssl.client.enabledProtocols";
+
+ private JMXConnectorServer cs;
+
+ // Construct and set keyStore properties from given map
+ static void setKeyStoreProperties(Map<String, Object> map) {
+
+ String keyStore = (String) map.get("-keystore");
+ keyStore = buildSourcePath(keyStore);
+ System.setProperty(KEYSTORE_PROPNAME, keyStore);
+ System.out.println("keyStore location = \"" + keyStore + "\"");
+
+ String password = (String) map.get("-keystorepassword");
+ System.setProperty(KEYSTORE_PWD_PROPNAME, password);
+ System.out.println("keyStore password = " + password);
+
+ }
+
+ // Construct and set trustStore properties from given map
+ static void setTrustStoreProperties(Map<String, Object> map) {
+
+ String trustStore = (String) map.get("-truststore");
+ trustStore = buildSourcePath(trustStore);
+ System.setProperty(TRUSTSTORE_PROPNAME, trustStore);
+ System.out.println("trustStore location = \"" + trustStore + "\"");
+
+ String password = (String) map.get("-truststorepassword");
+ System.setProperty(TRUSTSTORE_PWD_PROPNAME, password);
+ System.out.println("trustStore password = " + password);
+
+ }
+
+ /*
+ * First Debug properties and arguments are collect in expected
+ * map (argName, value) format, then calls original test's run method.
+ */
+ public static void main(String args[]) throws Exception {
+
+ System.out.println("=================================================");
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+
+ // Supported parameters list format is :
+ // "MainClass [-server <param-spec> ...] [-client <param-spec> ...]
+ // with <param-spec> either "-parami valuei" or "-parami"
+ HashMap<String, Object> serverMap = new HashMap<>() ;
+ int clientArgsIndex =
+ Utils.parseServerParameters(args, SERVER_CLASS_NAME, serverMap);
+
+ // Extract and records client params
+ String[] clientParams = null;
+ if (clientArgsIndex < args.length) {
+ int clientParamsSize = args.length - clientArgsIndex;
+ clientParams = new String[clientParamsSize];
+ System.arraycopy(args, clientArgsIndex, clientParams, 0, clientParamsSize);
+ } else {
+ clientParams = new String[0];
+ }
+
+ // Run test
+ SecurityTest test = new SecurityTest();
+ test.run(serverMap, clientParams);
+
+ }
+
+ // Return full path of filename in the test sopurce directory
+ private static String buildSourcePath(String filename) {
+ return System.getProperty("test.src") + File.separator + filename;
+ }
+
+ /*
+ * Collects security run params for server side.
+ */
+ private HashMap<String, Object> setServerSecurityEnv(Map<String, Object> map)
+ throws Exception {
+
+ // Creates Authentication environment from server side params
+ HashMap<String, Object> env = new HashMap<>();
+
+ // Retrieve and set keystore and truststore config if any
+ if (map.containsKey("-keystore") &&
+ map.get("-keystore") != null) {
+ setKeyStoreProperties(map);
+ }
+ System.out.println("Done keystore properties");
+
+ if (map.containsKey("-truststore") &&
+ map.get("-truststore") != null) {
+ setTrustStoreProperties(map);
+ }
+ System.out.println("Done truststore properties");
+
+ String value = null;
+ if ((value = (String)map.get("-mapType")) != null) {
+
+ // Case of remote password file with all authorized credentials
+ if (value.contains("x.password.file")) {
+ String passwordFileStr = buildSourcePath("password.properties");
+ env.put("jmx.remote.x.password.file", passwordFileStr);
+ System.out.println("Added " + passwordFileStr +
+ " file as jmx.remote.x.password.file");
+ }
+
+ // Case of dedicated authenticator class : TestJMXAuthenticator
+ if (value.contains("x.authenticator")) {
+ env.put("jmx.remote.authenticator", new TestJMXAuthenticator()) ;
+ System.out.println(
+ "Added \"jmx.remote.authenticator\" = TestJMXAuthenticator");
+ }
+
+ // Case of security config file with standard Authentication
+ if (value.contains("x.login.config.PasswordFileAuthentication")) {
+ String loginConfig = System.getProperty("login.config.file");
+
+ // Override the default JAAS configuration
+ System.setProperty("java.security.auth.login.config",
+ "file:" + loginConfig);
+ System.out.println("Overrided default JAAS configuration with " +
+ "\"java.security.auth.login.config\" = \"" + loginConfig + "\"") ;
+
+ env.put("jmx.remote.x.login.config", "PasswordFileAuthentication") ;
+ System.out.println(
+ "Added \"jmx.remote.x.login.config\" = " +
+ "\"PasswordFileAuthentication\"") ;
+
+ // redirects "password.file" property to file in ${test.src}
+ String passwordFileStr =
+ buildSourcePath(System.getProperty("password.file"));
+ System.setProperty("password.file", passwordFileStr);
+ System.out.println(
+ "Redirected \"password.file\" property value to = " +
+ passwordFileStr) ;
+ }
+
+ // Case of security config file with unexisting athentication config
+ if (value.contains("x.login.config.UnknownAuthentication")) {
+ String loginConfig = System.getProperty("login.config.file");
+
+ // Override the default JAAS configuration
+ System.setProperty("java.security.auth.login.config",
+ "file:" + loginConfig);
+ System.out.println("Overrided default JAAS configuration with " +
+ "\"java.security.auth.login.config\" = \"" + loginConfig + "\"") ;
+
+ env.put("jmx.remote.x.login.config", "UnknownAuthentication") ;
+ System.out.println(
+ "Added \"jmx.remote.x.login.config\" = " +
+ "\"UnknownAuthentication\"") ;
+
+ // redirects "password.file" property to file in ${test.src}
+ String passwordFileStr =
+ buildSourcePath(System.getProperty("password.file"));
+ System.setProperty("password.file", passwordFileStr);
+ System.out.println(
+ "Redirected \"password.file\" property value to = " +
+ passwordFileStr) ;
+ }
+
+ // Case of security config file with dedicated login module
+ if (value.contains("x.login.config.SampleLoginModule")) {
+ String loginConfig = System.getProperty("login.config.file");
+
+ // Override the default JAAS configuration
+ System.setProperty("java.security.auth.login.config",
+ "file:" + loginConfig);
+ System.out.println("Overrided default JAAS configuration with " +
+ "\"java.security.auth.login.config\" = \"" + loginConfig + "\"") ;
+
+ env.put("jmx.remote.x.login.config", "SampleLoginModule") ;
+ System.out.println(
+ "Added \"jmx.remote.x.login.config\" = " +
+ "\"SampleLoginModule\"") ;
+ }
+
+ // Simple rmi ssl authentication
+ if (value.contains(RMI_CLIENT_SOCKET_FACTORY_SSL)) {
+ env.put("jmx.remote.rmi.client.socket.factory",
+ new SslRMIClientSocketFactory()) ;
+ System.out.println(
+ "Added \"jmx.remote.rmi.client.socket.factory\"" +
+ " = SslRMIClientSocketFactory") ;
+ }
+
+ if (value.contains(RMI_SERVER_SOCKET_FACTORY_SSL)) {
+ if (value.contains(
+ "rmi.server.socket.factory.ssl.need.client.authentication")) {
+ // rmi ssl authentication with client authentication
+ env.put("jmx.remote.rmi.server.socket.factory",
+ new SslRMIServerSocketFactory(null, null, true)) ;
+ System.out.println(
+ "Added \"jmx.remote.rmi.server.socket.factory\"" +
+ " = SslRMIServerSocketFactory with client authentication") ;
+
+ } else if (value.contains("rmi.server.socket.factory.ssl.enabled.cipher.suites.md5")) {
+ // Allows all ciphering and protocols for testing purpose
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
+ env.put("jmx.remote.rmi.server.socket.factory",
+ new SslRMIServerSocketFactory(
+ new String[] {"SSL_RSA_WITH_RC4_128_MD5"}, null, false));
+ System.out.println(
+ "Added \"jmx.remote.rmi.server.socket.factory\"" +
+ " = SslRMIServerSocketFactory with SSL_RSA_WITH_RC4_128_MD5 cipher suite");
+
+ } else if (value.contains("rmi.server.socket.factory.ssl.enabled.cipher.suites.sha")) {
+ // Allows all ciphering and protocols for testing purpose
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
+ env.put("jmx.remote.rmi.server.socket.factory",
+ new SslRMIServerSocketFactory(
+ new String[] { "SSL_RSA_WITH_RC4_128_SHA" }, null, false)) ;
+ System.out.println(
+ "Added \"jmx.remote.rmi.server.socket.factory\"" +
+ " = SslRMIServerSocketFactory with SSL_RSA_WITH_RC4_128_SHA cipher suite") ;
+
+ } else if (value.contains("rmi.server.socket.factory.ssl.enabled.protocols.sslv3")) {
+ // Allows all ciphering and protocols for testing purpose
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
+ env.put("jmx.remote.rmi.server.socket.factory",
+ new SslRMIServerSocketFactory(null, new String[] {"SSLv3"}, false)) ;
+ System.out.println(
+ "Added \"jmx.remote.rmi.server.socket.factory\"" +
+ " = SslRMIServerSocketFactory with SSLv3 protocol") ;
+
+ } else if (value.contains("rmi.server.socket.factory.ssl.enabled.protocols.tlsv1")) {
+ // Allows all ciphering and protocols for testing purpose
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
+ env.put("jmx.remote.rmi.server.socket.factory",
+ new SslRMIServerSocketFactory(null, new String[] {"TLSv1"}, false)) ;
+ System.out.println(
+ "Added \"jmx.remote.rmi.server.socket.factory\"" +
+ " = SslRMIServerSocketFactory with TLSv1 protocol") ;
+
+ } else {
+ env.put("jmx.remote.rmi.server.socket.factory",
+ new SslRMIServerSocketFactory());
+ System.out.println(
+ "Added \"jmx.remote.rmi.server.socket.factory\"" +
+ " = SslRMIServerSocketFactory");
+ }
+ }
+ }
+
+ return env;
+ }
+
+ /*
+ * Create the MBeansServer side of the test and returns its address
+ */
+ private JMXServiceURL createServerSide(Map<String, Object> serverMap)
+ throws Exception {
+ final int NINETY_SECONDS = 90;
+
+ System.out.println("SecurityTest::createServerSide: Start") ;
+
+ // Prepare server side security env
+ HashMap<String, Object> env = setServerSecurityEnv(serverMap);
+
+ // Create and start mbean server and connector server
+ MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+ JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+ cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
+ cs.start();
+
+ // Waits availibility of connector server
+ Utils.waitReady(cs, NINETY_SECONDS);
+
+ JMXServiceURL addr = cs.getAddress();
+
+ System.out.println("SecurityTest::createServerSide: Done.") ;
+
+ return addr;
+ }
+
+ /*
+ * Creating command-line for running subprocess JVM:
+ *
+ * JVM command line is like:
+ * {test_jdk}/bin/java {defaultopts} -cp {test.class.path} {testopts} main
+ *
+ * {defaultopts} are the default java options set by the framework.
+ *
+ */
+ private List<String> buildCommandLine(String args[]) {
+
+ System.out.println("SecurityTest::buildCommandLine: Start") ;
+
+ List<String> opts = new ArrayList<>();
+ opts.add(JDKToolFinder.getJDKTool("java"));
+ opts.addAll(Arrays.asList(jdk.testlibrary.Utils.getTestJavaOpts()));
+
+ // We need to forward some properties to the client side
+ opts.add("-Dtest.src=" + System.getProperty("test.src"));
+
+ String usernameValue = System.getProperty(USERNAME_PROPERTY);
+ if (usernameValue != null) {
+ System.out.println("SecurityTest::buildCommandLine: "+
+ " forward username property to client side");
+ opts.add("-D" + USERNAME_PROPERTY + "=" + usernameValue);
+ }
+ String passwordValue = System.getProperty(PASSWORD_PROPERTY);
+ if (passwordValue != null) {
+ System.out.println("SecurityTest::buildCommandLine: "+
+ " forward password property to client side");
+ opts.add("-D" + PASSWORD_PROPERTY + "=" + passwordValue);
+ }
+
+ String enabledCipherSuites =
+ System.getProperty(RMI_SSL_CLIENT_ENABLEDCIPHERSUITES);
+ if (enabledCipherSuites != null) {
+ System.out.println("SecurityTest::buildCommandLine: "+
+ " forward enabledCipherSuites property to client side");
+ opts.add("-D" + RMI_SSL_CLIENT_ENABLEDCIPHERSUITES +
+ "=" + enabledCipherSuites);
+ }
+
+ String enabledProtocols =
+ System.getProperty(RMI_SSL_CLIENT_ENABLEDPROTOCOLS);
+ if (enabledProtocols != null) {
+ System.out.println("SecurityTest::buildCommandLine: "+
+ " forward enabledProtocols property to client side");
+ opts.add("-D" + RMI_SSL_CLIENT_ENABLEDPROTOCOLS +
+ "=" + enabledProtocols);
+ }
+
+ opts.add("-cp");
+ opts.add(System.getProperty("test.class.path", "test.class.path"));
+ opts.add(CLIENT_CLASS_MAIN);
+ opts.addAll(Arrays.asList(args));
+
+ System.out.println("SecurityTest::buildCommandLine: Done.") ;
+
+ return opts;
+ }
+
+ /**
+ * Runs SecurityTest$ClientSide with the passed options and redirects
+ * subprocess standard I/O to the current (parent) process. This provides a
+ * trace of what happens in the subprocess while it is runnning (and before
+ * it terminates).
+ *
+ * @param serviceUrlStr string representing the JMX service Url to connect to.
+ */
+ private int runClientSide(String args[], String serviceUrlStr) throws Exception {
+
+ System.out.println("SecurityTest::runClientSide: Start") ;
+
+ // Building command-line
+ List<String> opts = buildCommandLine(args);
+ opts.add("-serviceUrl");
+ opts.add(serviceUrlStr);
+
+ // Launch separate JVM subprocess
+ int exitCode = 0;
+ String[] optsArray = opts.toArray(new String[0]);
+ ProcessBuilder pb = new ProcessBuilder(optsArray);
+ Process p = ProcessTools.startProcess("SecurityTest$ClientSide", pb);
+
+ // Handling end of subprocess
+ try {
+ exitCode = p.waitFor();
+ if (exitCode != 0) {
+ System.out.println(
+ "Subprocess unexpected exit value of [" + exitCode +
+ "]. Expected 0.\n");
+ }
+ } catch (InterruptedException e) {
+ System.out.println("Parent process interrupted with exception : \n " + e + " :" );
+
+ // Parent thread unknown state, killing subprocess.
+ p.destroyForcibly();
+
+ throw new RuntimeException(
+ "Parent process interrupted with exception : \n " + e + " :" );
+
+ } finally {
+ if (p.isAlive()) {
+ p.destroyForcibly();
+ }
+
+ System.out.println("SecurityTest::runClientSide: Done") ;
+
+ return exitCode;
+ }
+
+ }
+
+ public void run(Map<String, Object> serverArgs, String clientArgs[]) {
+
+ System.out.println("SecurityTest::run: Start") ;
+ int errorCount = 0;
+
+ try {
+ // Initialise the server side
+ JMXServiceURL urlToUse = createServerSide(serverArgs);
+
+ // Run client side
+ errorCount = runClientSide(clientArgs, urlToUse.toString());
+
+ if ( errorCount == 0 ) {
+ System.out.println("SecurityTest::run: Done without any error") ;
+ } else {
+ System.out.println(
+ "SecurityTest::run: Done with " + errorCount + " error(s)");
+ throw new RuntimeException("errorCount = " + errorCount);
+ }
+
+ cs.stop();
+
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ private static class ClientSide {
+
+ private JMXConnector cc = null;
+ private MBeanServerConnection mbsc = null;
+
+ public static void main(String args[]) throws Exception {
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+
+ // Supported parameters list format is : "MainClass [-client <param-spec> ...]
+ // with <param-spec> either "-parami valuei" or "-parami"
+ HashMap<String, Object> clientMap = new HashMap<>() ;
+ Utils.parseClientParameters(args, CLIENT_CLASS_NAME, clientMap);
+
+ // Run test
+ ClientSide test = new ClientSide();
+ test.run(clientMap);
+ }
+
+ public void run(Map<String, Object> args) {
+
+ System.out.println("ClientSide::run: Start");
+ int errorCount = 0;
+
+ try {
+ // Setup client side parameters
+ HashMap<String, Object> env = new HashMap<>();
+
+ // If needed allows all ciphering and protocols for testing purpose
+ if (System.getProperty(RMI_SSL_CLIENT_ENABLEDCIPHERSUITES) != null) {
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+ }
+
+ // If needed allows all ciphering and protocols for testing purpose
+ if (System.getProperty(RMI_SSL_CLIENT_ENABLEDPROTOCOLS) != null) {
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+ }
+
+ // Retrieve and set keystore and truststore config if any
+ if (args.containsKey("-keystore") &&
+ args.get("-keystore") != null) {
+ SecurityTest.setKeyStoreProperties(args);
+ }
+ if (args.containsKey("-truststore") &&
+ args.get("-truststore") != null) {
+ SecurityTest.setTrustStoreProperties(args);
+ }
+
+ Object value = args.get("-mapType");
+ if ((value != null) &&
+ value.equals("credentials")) {
+ String username = System.getProperty("username");
+ String password = System.getProperty("password");
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "add \"jmx.remote.credentials\" = \"" +
+ username + "\", \"" + password + "\"");
+ env.put("jmx.remote.credentials",
+ new String[] { username , password });
+ }
+
+ String expectedThrowable = (String) args.get("-expectedThrowable");
+
+ String authCallCountName = "-expectedAuthenticatorCallCount";
+ int authCallCountValue = 0;
+ if (args.containsKey(authCallCountName)) {
+ authCallCountValue =
+ (new Integer((String) args.get(authCallCountName))).intValue();
+ }
+
+ try {
+ // Get a connection to remote mbean server
+ JMXServiceURL addr = new JMXServiceURL((String)args.get("-serviceUrl"));
+ cc = JMXConnectorFactory.connect(addr,env);
+ mbsc = cc.getMBeanServerConnection();
+
+ // In case we should have got an exception
+ if (expectedThrowable != null) {
+ System.out.println("ClientSide::run: (ERROR) " +
+ " Connect did not fail with expected " + expectedThrowable);
+ errorCount++;
+ } else {
+ System.out.println("ClientSide::run: (OK) Connect succeed");
+ }
+ } catch (Throwable e) {
+ Utils.printThrowable(e, true);
+ if (expectedThrowable != null) {
+ if (Utils.compareThrowable(e, expectedThrowable)) {
+ System.out.println("ClientSide::run: (OK) " +
+ "Connect failed with expected " + expectedThrowable);
+ } else {
+ System.out.println("ClientSide::run: (ERROR) Connect failed with " +
+ e.getClass() + " instead of expected " +
+ expectedThrowable);
+ errorCount++;
+ }
+ } else {
+ System.out.println("ClientSide::run: (ERROR) " +
+ "Connect failed with exception");
+ errorCount++;
+ }
+ }
+
+ // Depending on the client state,
+ // perform some requests
+ if (mbsc != null && errorCount == 0) {
+ // Perform some little JMX requests
+ System.out.println("ClientSide::run: Start sending requests");
+
+ doRequests();
+
+ // In case authentication has been used we check how it did.
+ if (authCallCountValue != 0) {
+ errorCount += checkAuthenticator(mbsc, authCallCountValue);
+ }
+ }
+ } catch (Exception e) {
+ Utils.printThrowable(e, true);
+ errorCount++;
+ } finally {
+ // Terminate the JMX Client if any
+ if (cc != null) {
+ try {
+ cc.close();
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++;
+ }
+ }
+ }
+
+ System.out.println("ClientSide::run: Done");
+
+ // Handle result
+ if (errorCount != 0) {
+ throw new RuntimeException();
+ }
+ }
+
+ private void doRequests() throws Exception {
+
+ // Send some requests to the remote JMX server
+ ObjectName objName1 =
+ new ObjectName("TestDomain:class=MBS_Light,rank=1");
+ String mbeanClass = "MBS_Light";
+ Exception exception = new Exception("MY TEST EXCEPTION");
+ Attribute attException = new Attribute("AnException", exception);
+ Error error = new Error("MY TEST ERROR");
+ Attribute attError = new Attribute("AnError", error);
+ String opParamString = "TOTORO";
+ RjmxMBeanParameter opParam = new RjmxMBeanParameter(opParamString);
+ Object[] params1 = {opParamString};
+ String[] sig1 = {"java.lang.String"};
+ Object[] params2 = {opParam};
+ String[] sig2 = {"RjmxMBeanParameter"};
+
+ // Create and register the MBean
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::doRequests: Create and register the MBean");
+ mbsc.createMBean(mbeanClass, objName1);
+ if (!mbsc.isRegistered(objName1)) {
+ throw new Exception("Unable to register an MBean");
+ }
+
+ // Set attributes of the MBean
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::doRequests: Set attributes of the MBean");
+ mbsc.setAttribute(objName1, attException);
+ mbsc.setAttribute(objName1, attError);
+
+ // Get attributes of the MBean
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::doRequests: Get attributes of the MBean");
+ Exception retException =
+ (Exception) mbsc.getAttribute(objName1,"AnException");
+ if (!retException.getMessage().equals(exception.getMessage())) {
+ System.out.println("Expected = " + exception);
+ System.out.println("Got = " + retException);
+ throw new Exception("Attribute AnException not as expected");
+ }
+ Error retError = (Error) mbsc.getAttribute(objName1, "AnError");
+ if (!retError.getMessage().equals(error.getMessage())) {
+ System.out.println("Expected = " + error);
+ System.out.println("Got = " + retError);
+ throw new Exception("Attribute AnError not as expected");
+ }
+
+ // Invoke operations on the MBean
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::doRequests: Invoke operations on the MBean");
+ RjmxMBeanParameter res1 =
+ (RjmxMBeanParameter) mbsc.invoke(objName1, "operate1", params1, sig1);
+ if (!res1.equals(opParam)) {
+ System.out.println("Expected = " + opParam);
+ System.out.println("Got = " + res1);
+ throw new Exception("Operation operate1 behaved badly");
+ }
+ String res2 =
+ (String) mbsc.invoke(objName1, "operate2", params2, sig2);
+ if (!res2.equals(opParamString)) {
+ System.out.println("Expected = " + opParamString);
+ System.out.println("Got = " + res2);
+ throw new Exception("Operation operate2 behaved badly");
+ }
+
+ // Unregister the MBean
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::doRequests: Unregister the MBean");
+ mbsc.unregisterMBean(objName1);
+ if (mbsc.isRegistered(objName1)) {
+ throw new Exception("Unable to unregister an MBean");
+ }
+ }
+
+ /**
+ * Make some check about the instance of TestJMXAuthenticator.
+ * The authenticator is supposed to have set some properties on
+ * a ServerDelegate MBean.
+ * We compare the number of times it has been called with the expected value.
+ * We also check the Principal that has been given to the authenticator
+ * was not null.
+ * That method is of use to authentication with the JSR 262.
+ * @param mbs
+ * @param expectedAuthenticatorCallCount
+ * @return The number of errors encountered.
+ * @throws java.lang.Exception
+ */
+ protected int checkAuthenticator(MBeanServerConnection mbs,
+ int expectedAuthenticatorCallCount) throws Exception {
+ int errorCount = 0;
+
+ // Ensure the authenticator has been called the right number
+ // of times.
+ int callCount =
+ ((Integer) mbs.getAttribute(
+ new ObjectName(SERVER_DELEGATE_MBEAN_NAME),
+ "TestJMXAuthenticatorCallCount")).intValue();
+
+ if (callCount == expectedAuthenticatorCallCount) {
+ System.out.println("---- OK Authenticator has been called "
+ + expectedAuthenticatorCallCount + " time");
+ } else {
+ errorCount++;
+ System.out.println("---- ERROR Authenticator has been called " + callCount
+ + " times in place of " + expectedAuthenticatorCallCount);
+ }
+
+ // Ensure the provider has been called with
+ // a non null Principal.
+ String principalString =
+ (String) mbs.getAttribute(
+ new ObjectName(SERVER_DELEGATE_MBEAN_NAME),
+ "TestJMXAuthenticatorPrincipalString");
+
+ if (principalString == null) {
+ errorCount++;
+ System.out.println("---- ERROR Authenticator has been called"
+ + " with a null Principal");
+ } else {
+ if (principalString.length() > 0) {
+ System.out.println("---- OK Authenticator has been called"
+ + " with the Principal " + principalString);
+ } else {
+ errorCount++;
+ System.out.println("---- ERROR Authenticator has been called"
+ + " with an empty Principal");
+ }
+ }
+
+ return errorCount;
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/security/ServerDelegate.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.management.remote.JMXServiceURL ;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.StandardMBean;
+
+/**
+ * This class defines an MBean that can be registered and used on client side
+ * to handle informations or properties of the remote server.
+ *
+ * For example, this MBean can store IOR addresses
+ * of RMI/IIOP connector(s) used in a test.
+ *
+ * That MBean might not be used for testing purpose itself.
+ */
+public class ServerDelegate implements ServerDelegateMBean, MBeanRegistration {
+
+ private MBeanServer mbeanServer = null;
+ private List<JMXServiceURL> addresses = null;
+ private String port;
+ private static String javaVersion = System.getProperty("java.version");
+ private int sqeJmxwsCredentialsProviderCallCount = 0;
+ private String jmxwsCredentialsProviderUrl = null;
+ private int testJMXAuthenticatorCallCount = 0;
+ private Principal testJMXAuthenticatorPrincipal = null;
+
+ @SqeDescriptorKey("NO PARAMETER CONSTRUCTOR ServerDelegate")
+ public ServerDelegate() {
+ addresses = new ArrayList<JMXServiceURL>();
+ }
+
+ public ObjectName preRegister(MBeanServer server, ObjectName name)
+ throws Exception {
+ // Initialize MBeanServer attribute
+ mbeanServer = server;
+ return name;
+ }
+ public void postRegister(Boolean registrationDone) {
+ }
+ public void preDeregister() throws Exception {
+ }
+ public void postDeregister() {
+ }
+
+ public void addAddress(JMXServiceURL url) {
+ addresses.add(url) ;
+ }
+
+ public List<JMXServiceURL> getAddresses() {
+ return addresses ;
+ }
+
+ public void setPort(String p) {
+ port = p ;
+ }
+
+ public String getPort() {
+ return port ;
+ }
+
+ public String getJavaVersion() {
+ return javaVersion;
+ }
+
+ public void sqeJmxwsCredentialsProviderCalled() {
+ sqeJmxwsCredentialsProviderCallCount++;
+ }
+
+ public int getSqeJmxwsCredentialsProviderCallCount() {
+ return sqeJmxwsCredentialsProviderCallCount;
+ }
+
+ public void setJmxwsCredentialsProviderUrl(String url) {
+ jmxwsCredentialsProviderUrl = url;
+ }
+
+ public String getJmxwsCredentialsProviderUrl() {
+ return jmxwsCredentialsProviderUrl;
+ }
+
+ public void testJMXAuthenticatorCalled() {
+ testJMXAuthenticatorCallCount++;
+ }
+
+ public int getTestJMXAuthenticatorCallCount() {
+ return testJMXAuthenticatorCallCount;
+ }
+
+ public void setTestJMXAuthenticatorPrincipal(Principal principal) {
+ testJMXAuthenticatorPrincipal = principal;
+ }
+
+ public String getTestJMXAuthenticatorPrincipalString() {
+ if ( testJMXAuthenticatorPrincipal != null ) {
+ return testJMXAuthenticatorPrincipal.toString();
+ }
+
+ return null;
+ }
+
+ /**
+ * Instantiates and registers a StandardMBean in the MBean server.
+ *
+ * @param implementationClassName
+ * The implementation class name of the MBean.
+ * @param interfaceClassName
+ * The management interface class name of the MBean.
+ * @param isMXBean
+ * If true, the resultant MBean is an MXBean.
+ * @param name
+ * The object name of the StandardMBean.
+ */
+ @SuppressWarnings("unchecked")
+ public void createStandardMBean(
+ String implementationClassName,
+ String interfaceClassName,
+ boolean isMXBean,
+ ObjectName name)
+ throws Exception {
+
+ Object implementation =
+ Class.forName(implementationClassName).newInstance();
+ Class<Object> interfaceClass = interfaceClassName == null ? null :
+ (Class<Object>)Class.forName(interfaceClassName);
+
+ // Create the StandardMBean
+ StandardMBean standardMBean = new StandardMBean(
+ implementation,
+ interfaceClass,
+ isMXBean);
+
+ // Register the StandardMBean
+ mbeanServer.registerMBean(standardMBean, name);
+ }
+
+ /**
+ * Instantiates and registers a StandardMBean in the MBean server.
+ * The object will use standard JMX design pattern to determine
+ * the management interface associated with the given implementation.
+ */
+ @SuppressWarnings("unchecked")
+ public void createStandardMBean(
+ String implementationClassName,
+ boolean isMXBean,
+ ObjectName name)
+ throws Exception {
+
+ createStandardMBean(implementationClassName, null, isMXBean, name);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/security/ServerDelegateMBean.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.Principal;
+import java.util.List;
+
+import javax.management.remote.JMXServiceURL ;
+import javax.management.ObjectName;
+
+@SqeDescriptorKey("INTERFACE ServerDelegateMBean")
+public interface ServerDelegateMBean {
+ @SqeDescriptorKey("ATTRIBUTE Address")
+ public void addAddress(JMXServiceURL url);
+
+ @SqeDescriptorKey("ATTRIBUTE Address")
+ public List<JMXServiceURL> getAddresses();
+
+ public String getPort();
+ public void setPort(String p);
+
+ public String getJavaVersion();
+
+ public void sqeJmxwsCredentialsProviderCalled();
+ public int getSqeJmxwsCredentialsProviderCallCount();
+
+ public void setJmxwsCredentialsProviderUrl(String url);
+ public String getJmxwsCredentialsProviderUrl();
+
+ public void testJMXAuthenticatorCalled();
+ public int getTestJMXAuthenticatorCallCount();
+
+ public void setTestJMXAuthenticatorPrincipal(Principal principal);
+ public String getTestJMXAuthenticatorPrincipalString();
+
+ public void createStandardMBean(
+ String implementationClassName,
+ String interfaceClassName,
+ boolean isMXBean,
+ ObjectName name)
+ throws Exception;
+
+ public void createStandardMBean(
+ String implementationClassName,
+ boolean isMXBean,
+ ObjectName name)
+ throws Exception;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/security/Simple.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+//import java.beans.ConstructorProperties;
+import javax.management.ConstructorParameters;
+
+/**
+ * This class defines a simple standard MBean.
+ */
+public class Simple implements SimpleMBean {
+
+ private String attribute = "initial_value";
+ private boolean operationInvoked = false;
+ private boolean operation2Invoked = false;
+
+ @SqeDescriptorKey("NO PARAMETER CONSTRUCTOR Simple")
+ public Simple() {
+ }
+
+ @SqeDescriptorKey("TWO PARAMETERS CONSTRUCTOR Simple")
+ @ConstructorParameters({"unused1", "unused2"})
+ public Simple(@SqeDescriptorKey("CONSTRUCTOR PARAMETER unused1")int unused1,
+ @SqeDescriptorKey("CONSTRUCTOR PARAMETER unused2")int unused2) {
+ }
+
+ public String getAttribute() {
+ return attribute;
+ }
+ public void setAttribute(String s) {
+ attribute = s;
+ }
+ public boolean getOperationInvoked() {
+ return operationInvoked;
+ }
+ public boolean getOperation2Invoked() {
+ return operation2Invoked;
+ }
+
+ public void operation() {
+ operationInvoked = true;
+ return;
+ }
+
+ public String operation2(int i) {
+ operation2Invoked = true;
+ return String.valueOf(i);
+ }
+
+ public void reset() {
+ attribute = "initial_value";
+ operationInvoked = false;
+ operation2Invoked = false;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/security/SimpleListener.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// JDK
+import java.util.Vector;
+
+// JMX
+import javax.management.NotificationListener;
+import javax.management.Notification;
+
+public class SimpleListener implements NotificationListener {
+ private boolean received = false;
+ private String type = null;
+ private Object handback = null;
+ private Vector<Object> handbacks = new Vector<Object>();
+ private int nbrec = 0;
+
+ public synchronized void handleNotification(Notification notification,
+ Object handback) {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "SimpleListener::handleNotification :" + notification);
+ try {
+ received = true;
+ type = notification.getType();
+ this.handback = handback;
+ handbacks.add(handback);
+ nbrec++;
+ notify();
+ } catch(Exception e) {
+ System.out.println("(ERROR) SimpleListener::handleNotification :"
+ + " Caught exception "
+ + e) ;
+ }
+ }
+
+ public synchronized boolean isNotificationReceived() {
+ boolean ret = received;
+ reset();
+ return ret;
+ }
+
+ public synchronized Object[] waitForMultiNotifications(int nb) {
+ while(true) {
+ if(nbrec < nb) {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "SimpleListener::waitForMultiNotifications wait");
+ try {
+ wait();
+ } catch(InterruptedException ie) {
+ // OK : we wait for being interrupted
+ }
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "SimpleListener::waitForMultiNotifications wait over");
+ }
+ else
+ break;
+ }
+ Object[] ret = handbacks.toArray();
+ reset();
+ return ret;
+ }
+
+ private void reset() {
+ received = false;
+ handback = null;
+ handbacks.removeAllElements();
+ type = null;
+ }
+
+ public synchronized Object waitForNotificationHB() {
+ while(true) {
+ if(!received) {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "SimpleListener::waitForNotificationHB wait");
+ try {
+ wait();
+ } catch(InterruptedException ie) {
+ // OK : we wait for being interrupted
+ }
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "SimpleListener::waitForNotificationHB received");
+ }
+ else
+ break;
+ }
+ Object ret = handback;
+ reset();
+ return ret;
+ }
+
+ public synchronized String waitForNotification() {
+ while(true) {
+ if(!received) {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "SimpleListener::waitForNotification wait");
+ try {
+ wait();
+ } catch(InterruptedException ie) {
+ // OK : we wait for being interrupted
+ }
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "SimpleListener::waitForNotification received");
+ }
+ else
+ break;
+ }
+ String ret = type;
+ reset();
+ return ret;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/security/SimpleMBean.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 interface defines a simple standard MBean.
+ */
+@SqeDescriptorKey("INTERFACE SimpleMBean")
+public interface SimpleMBean {
+
+ @SqeDescriptorKey("ATTRIBUTE Attribute")
+ public String getAttribute();
+
+ @SqeDescriptorKey("ATTRIBUTE Attribute")
+ public void setAttribute(String s);
+
+ @SqeDescriptorKey("ATTRIBUTE OperationInvoked")
+ public boolean getOperationInvoked();
+
+ @SqeDescriptorKey("ATTRIBUTE Operation2Invoked")
+ public boolean getOperation2Invoked();
+
+ // Void operation
+ // The associated MBeanOperationInfo is mapped to OpenMBeanOperationInfo
+ // => openType is added to the descriptor
+ @SqeDescriptorKey(value = "OPERATION operation",
+ descriptorFields = {"openType=SimpleType.VOID"})
+ public void operation();
+
+ @SqeDescriptorKey("OPERATION operation2")
+ public String operation2(int i);
+
+ // Void operation
+ // The associated MBeanOperationInfo is mapped to OpenMBeanOperationInfo
+ // => openType is added to the descriptor
+ @SqeDescriptorKey(value = "OPERATION reset",
+ descriptorFields = {"openType=SimpleType.VOID"})
+ public void reset();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/security/SqeDescriptorKey.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import javax.management.DescriptorKey;
+
+/**
+ * That annotation is usable everywhere DescriptorKey is (and even more).
+ * It is for use to test that you can retrieve the SqeDescriptorKey into the
+ * appropriate Descriptor instances as built by the JMX runtime.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface SqeDescriptorKey {
+ @DescriptorKey("sqeDescriptorKey")
+ String value();
+
+ // List descriptor fields that may be added or may be updated
+ // when retrieving an MBeanInfo using a JMXWS connection compared to the
+ // MBeanInfo returned by a local MBeanServer.
+ // The annotation format is :
+ // <descriptorFieldName>=<descriptorFieldValue>
+ // The values actually handled by the test suite are :
+ // openType=SimpleType.VOID
+ @DescriptorKey("descriptorFields")
+ String[] descriptorFields() default {};
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/security/TestJMXAuthenticator.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.Principal;
+
+import javax.management.Attribute;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.remote.JMXAuthenticator;
+import javax.management.remote.JMXPrincipal;
+import javax.security.auth.Subject;
+
+public final class TestJMXAuthenticator implements JMXAuthenticator {
+
+ private String protocol = "";
+ private MBeanServer mbs = null;
+
+ public TestJMXAuthenticator() {
+ }
+
+ public TestJMXAuthenticator(String protocol) {
+ this.protocol = protocol;
+ }
+
+ public TestJMXAuthenticator(String protocol, MBeanServer mbs) {
+ this.protocol = protocol;
+ this.mbs = mbs;
+ }
+
+ public Subject authenticate(Object credentials) {
+
+ String credentials_username = "";
+ String credentials_password = "";
+ Principal aPrincipal = null;
+
+ credentials_username = ((String[]) credentials)[0];
+ credentials_password = ((String[]) credentials)[1];
+
+ String authenticated_username = System.getProperty("susername");
+ String authenticated_password = System.getProperty("spassword");
+ String principal = System.getProperty("principal");
+
+ System.out.println("TestJMXAuthenticator::authenticate: Start");
+ System.out.println("TestJMXAuthenticator::authenticate: credentials username = " +
+ credentials_username);
+ System.out.println("TestJMXAuthenticator::authenticate: credentials password = " +
+ credentials_password);
+ System.out.println("TestJMXAuthenticator::authenticate: authenticated username = " +
+ authenticated_username);
+ System.out.println("TestJMXAuthenticator::authenticate: authenticated password = " +
+ authenticated_password);
+ System.out.println("TestJMXAuthenticator::authenticate: principal used for " +
+ "authorization = " + principal);
+
+ if (credentials_username.equals(authenticated_username) &&
+ credentials_password.equals(authenticated_password)) {
+ System.out.println("TestJMXAuthenticator::authenticate: " +
+ "Authenticator should succeed");
+ } else {
+ System.out.println("TestJMXAuthenticator::authenticate: " +
+ "Authenticator should reject");
+ throw new SecurityException("TestJMXAuthenticator throws EXCEPTION");
+ }
+
+ // At this point, authentication has succeeded
+ // (no SecurityException thrown).
+ //
+ // If no authorization is required, the returned subject (empty or not)
+ // is useless.
+ // Otherwise, the returned subject must define a principal
+ // and authorization will be performed against this principal.
+ //
+ // Note that this custom JMXAuthenticator is used for test purpose and
+ // the username used to perform authentication may be different from the
+ // username used to perform authorization.
+ //
+ Subject subject = new Subject();
+
+ if (principal != null) {
+ System.out.println("TestJMXAuthenticator::authenticate: " +
+ "Add " + principal + " principal to the returned subject");
+ subject.getPrincipals().add(new JMXPrincipal(principal));
+ }
+
+ return subject;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/security/TestSampleLoginModule.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Map;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+
+
+public final class TestSampleLoginModule implements LoginModule {
+
+ private Subject subject;
+ private CallbackHandler callbackHandler;
+ private Map<String, ?> sharedState;
+ private Map<String, ?> options;
+
+ public TestSampleLoginModule() {
+ }
+
+ public void initialize(Subject subject,
+ CallbackHandler callbackHandler,
+ Map<String,?> sharedState,
+ Map<String,?> options) {
+
+ this.subject = subject;
+ this.callbackHandler = callbackHandler;
+ this.sharedState = sharedState;
+ this.options = options;
+ }
+
+ /*
+ * Authenticate the user by comparing the values of the java properties
+ * (username and password) against the values of the credentials.
+ * */
+ public boolean login() throws LoginException {
+
+ String credentials_username = null;
+ String credentials_password = null;
+ String authenticated_username = System.getProperty("susername");
+ String authenticated_password = System.getProperty("spassword");
+
+ System.out.println("TestSampleLoginModule::login: Start");
+
+ // First retreive the credentials {username, password} from
+ // the callback handler
+ Callback[] callbacks = new Callback[2];
+ callbacks[0] = new NameCallback("username");
+ callbacks[1] = new PasswordCallback("password", false);
+ try {
+ callbackHandler.handle(callbacks);
+ credentials_username = ((NameCallback)callbacks[0]).getName();
+ credentials_password = new String(((PasswordCallback)callbacks[1]).
+ getPassword());
+ } catch (Exception e) {
+ throw new LoginException(e.toString());
+ }
+
+ System.out.println("TestSampleLoginModule::login: credentials username = " +
+ credentials_username);
+ System.out.println("TestSampleLoginModule::login: credentials password = " +
+ credentials_password);
+ System.out.println("TestSampleLoginModule::login: authenticated username = " +
+ authenticated_username);
+ System.out.println("TestSampleLoginModule::login: authenticated password = " +
+ authenticated_password);
+
+ if (credentials_username.equals(authenticated_username) &&
+ credentials_password.equals(authenticated_password)) {
+ System.out.println("TestSampleLoginModule::login: " +
+ "Authentication should succeed");
+ return true;
+ } else {
+ System.out.println("TestSampleLoginModule::login: " +
+ "Authentication should reject");
+ throw new LoginException("TestSampleLoginModule throws EXCEPTION");
+ }
+ }
+
+ public boolean commit() throws LoginException {
+ return true;
+ }
+
+ public boolean abort() throws LoginException {
+ return true;
+ }
+
+ public boolean logout() throws LoginException {
+ return true;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/security/Utils.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,424 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.lang.reflect.Method;
+import javax.management.remote.JMXConnectorServerMBean;
+
+// utility class for MXBean* tests coming from JMX Tonga test suite
+class Utils {
+
+ private static final String SERVER_SIDE_NAME = "-server";
+ private static final String CLIENT_SIDE_NAME = "-client";
+
+ // DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property
+ private static final String DEBUG_HEADER = "[debug] ";
+
+ // DEBUG levels
+ private static int selectedDebugLevel = 0;
+ static final int DEBUG_STANDARD = 1;
+ static final int DEBUG_VERBOSE = 2; // Mainly used for stress tests
+ static final int DEBUG_ALL = DEBUG_STANDARD | DEBUG_VERBOSE;
+
+ static void parseDebugProperties() {
+ int level = 0;
+ Properties p = System.getProperties();
+
+ // get selected levels
+ if (p.getProperty("DEBUG_STANDARD") != null) {
+ level |= DEBUG_STANDARD;
+ }
+
+ if (p.getProperty("DEBUG_VERBOSE") != null) {
+ level |= DEBUG_VERBOSE;
+ }
+
+ if (p.getProperty("DEBUG_ALL") != null) {
+ level |= DEBUG_ALL;
+ }
+
+ selectedDebugLevel = level;
+ }
+
+ /**
+ * Reproduces the original parsing and collection of test parameters
+ * from the DTonga JMX test suite.
+ *
+ * Collects passed args and returns them in a map(argname, value) structure,
+ * which will be then propagated as necessary to various called methods.
+ */
+ static Map<String, Object> parseParameters(String args[])
+ throws Exception {
+ Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Start");
+ HashMap<String, Object> map = new HashMap<>();
+
+ for ( int i = 0; i < args.length; i++ ) {
+ if ( args[i].trim().startsWith("-") ) {
+ if ((i+1) < args.length && !args[i+1].startsWith("-") ) {
+ Utils.debug(DEBUG_STANDARD,
+ "TestRoot::parseParameters: added in map = " +
+ args[i] +
+ " with value " +
+ args[i+1]) ;
+ map.put(args[i].trim(), args[i+1].trim()) ;
+ } else if ((i+1) < args.length && args[i+1].startsWith("-") ||
+ (i+1) == args.length ) {
+ Utils.debug(DEBUG_STANDARD,
+ "TestRoot::parseParameters: added in map = " +
+ args[i] +
+ " with null value") ;
+ map.put(args[i].trim(), null) ;
+ } else {
+ System.out.println(
+ "TestRoot::parseParameters: (WARNING) not added in map = " +
+ args[i]) ;
+ }
+ }
+ }
+
+ Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Done") ;
+ return map ;
+ }
+
+ // Parse server parameters and put them in passed serverMap
+ static int parseServerParameters(String args[],
+ String serverSideName,
+ Map<String, Object> serverMap )
+ throws Exception {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ serverSideName + "::parseServerParameters: Start");
+
+ int nextIndex = 0;
+ boolean seenServerFlag = false;
+
+ for ( int i = 0; i < args.length; i++ ) {
+ // Case of reaching "-server" flag parameter
+ if (args[i].equals(SERVER_SIDE_NAME)) {
+ if (!seenServerFlag) {
+ seenServerFlag = true;
+ continue;
+ } else {
+ // Already parsing server params, invalid params list
+ Utils.debug(Utils.DEBUG_STANDARD,
+ serverSideName + "::parseParameters: Invalid " +
+ args[i] + " parameter detected in " +
+ SERVER_SIDE_NAME + " parameters list");
+ nextIndex = -1;
+ throw new RuntimeException("Invalid Parameter list");
+ }
+ }
+
+ // Case of reaching "-client" flag parameter
+ if (args[i].equals(CLIENT_SIDE_NAME)) {
+ // While parsing server parameters, then parsing is done.
+ Utils.debug(Utils.DEBUG_STANDARD,
+ serverSideName + "::parseServerParameters: Parsing of " +
+ SERVER_SIDE_NAME + " parameters done.");
+ return i;
+ }
+
+ i = parseParamAtIndex(args, i, serverMap);
+ nextIndex = i;
+ }
+
+ Utils.debug(Utils.DEBUG_STANDARD,
+ serverSideName + "::parseServerParameters: Parsing of parameters done");
+
+ return nextIndex;
+ }
+
+ // Parse client parameters and put them in passed clientMap
+ static void parseClientParameters(String args[],
+ String clientSideName,
+ Map<String, Object> clientMap )
+ throws Exception {
+
+ Utils.debug(Utils.DEBUG_STANDARD,
+ clientSideName + "::parseClientParameters: Start");
+
+ boolean seenClientFlag = false;
+
+ for ( int i = 0; i < args.length; i++ ) {
+ // Case of reaching "-client" flag parameter
+ if (args[i].equals(CLIENT_SIDE_NAME)) {
+ if (!seenClientFlag) {
+ seenClientFlag = true;
+ continue;
+ } else {
+ // Already parsing client params, invalid params list
+ Utils.debug(Utils.DEBUG_STANDARD,
+ clientSideName + "::parseClientParameters: Invalid " +
+ CLIENT_SIDE_NAME + " parameter detected in " +
+ CLIENT_SIDE_NAME + " parameters list.");
+ throw new RuntimeException("Invalid parameter in " +
+ clientSideName + " parameter list");
+ }
+ }
+
+ // Case of reaching "-server" flag parameter
+ if (args[i].equals(SERVER_SIDE_NAME)) {
+ // While parsing client parameters, invalid parameter list.
+ Utils.debug(Utils.DEBUG_STANDARD,
+ clientSideName + "::parseClientParameters: Invalid " +
+ SERVER_SIDE_NAME + " parameter inside " +
+ CLIENT_SIDE_NAME + " parameters list.");
+ throw new RuntimeException("Invalid parameter in " +
+ clientSideName + " parameter list");
+ }
+
+ i = parseParamAtIndex(args, i, clientMap);
+ }
+
+ Utils.debug(Utils.DEBUG_STANDARD,
+ clientSideName + "::parseClientParameters: Parsing of parameters done.");
+ }
+
+ // Add param found at index to passed map
+ // We only accept either "-param value" or "-param" form.
+ // The "value" form is invalid but just ignored.
+ private static int parseParamAtIndex(String args[],
+ int index,
+ Map<String, Object> map) {
+
+ if (args[index].trim().startsWith("-") ) {
+ // Case of a "-param value" form
+ if ((index+1) < args.length && !args[index+1].startsWith("-") ) {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "TestRoot::parseParamAtIndex: added in map = "
+ + args[index]
+ + " with value "
+ + args[index+1]) ;
+ // adding ("param", value) to the passed map
+ map.put(args[index].trim(), args[index+1].trim()) ;
+ // value should not be parsed a second time
+ return index+1;
+ }
+ // Case of a "-param" form (flag parameter)
+ else if (((index+1) < args.length && args[index+1].startsWith("-")) ||
+ (index+1) == args.length ) {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "TestRoot::parseParamAtIndex: added in map = "
+ + args[index]
+ + " with null value") ;
+ // adding ("param", null) to passed map
+ map.put(args[index].trim(), null) ;
+ }
+ } else {
+ // Unsupported "value" alone parameter
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "TestRoot::parseParamAtIndex: invalid " +
+ " value-alone \"" + args[index] + "\" parameter." +
+ " Parameter ignored.");
+ }
+
+ return index;
+ }
+
+ /**
+ * This method is to be used in all tests to print anything
+ * that is temporary.
+ * Printing is done only when debug is activated by the property DEBUG.
+ * Printing depends also on the DEBUG_LEVEL property.
+ * Here it encapsulates a System.out.println.
+ */
+ static void debug(int level, String line) {
+ if ((selectedDebugLevel & level) != 0) {
+ System.out.println(DEBUG_HEADER + line);
+ }
+ }
+
+ /**
+ * Do print stack trace when withStack is true.
+ * Does try to call getTargetException() and getTargetError() then
+ * print embedded stacks in the case of an Exception wrapping
+ * another Exception or an Error. Recurse until no more wrapping
+ * is found.
+ */
+ static void printThrowable(Throwable theThro, boolean withStack) {
+ try {
+ if (withStack) {
+ theThro.printStackTrace(System.out);
+ }
+ if (theThro instanceof Exception) {
+ Exception t = (Exception) theThro;
+ Method target = null;
+ String blank = " ";
+ try {
+ target = t.getClass().getMethod("getTargetException",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetException method could be there or not
+ }
+ System.out.println(blank + t.getClass() + "==>" + t.getMessage());
+ while (target != null) {
+ try {
+ t = (Exception) target.invoke(t,
+ (java.lang.Object[]) null);
+ } catch (Exception ee) {
+ t = null;
+ }
+ try {
+ if (t != null) {
+ blank = blank + " ";
+ System.out.println(blank + t.getClass() + "==>" +
+ t.getMessage());
+ try {
+ target =
+ t.getClass().getMethod("getTargetException",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetException method could be there or not }
+ }
+ } else {
+ target = null;
+ }
+ } catch (Exception ee) {
+ target = null;
+ }
+ }
+
+ // We may have exceptions wrapping an Error then it is
+ // getTargetError that is likely to be called
+ try {
+ target = ((Exception) theThro).getClass().getMethod("getTargetError",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetError method could be there or not
+ }
+ Throwable err = theThro;
+ while (target != null) {
+ try {
+ err = (Error) target.invoke(err,
+ (java.lang.Object[]) null);
+ } catch (Exception ee) {
+ err = null;
+ }
+ try {
+ if (err != null) {
+ blank = blank + " ";
+ System.out.println(blank + err.getClass() + "==>" +
+ err.getMessage());
+ if (withStack) {
+ err.printStackTrace(System.out);
+ }
+ try {
+ target = err.getClass().getMethod("getTargetError",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetError method could be there or not
+ }
+ } else {
+ target = null;
+ }
+ } catch (Exception ee) {
+ target = null;
+ }
+ }
+ } else {
+ System.out.println("Throwable is : " + theThro);
+ }
+ } catch (Throwable x) {
+ System.out.println("Exception : raised in printException : " + x);
+ }
+ }
+
+ /**
+ * Wait up to maxTimeInSeconds second(s) the given JMX connector server
+ * comes up (which means isActive returns true).
+ * If it fails to do so we throw a RunTime exception.
+ */
+ static void waitReady(JMXConnectorServerMBean server,
+ int maxTimeInSeconds) throws Exception {
+ int elapsed = 0;
+
+ while (!server.isActive() && elapsed < maxTimeInSeconds) {
+ Thread.sleep(1000);
+ elapsed++;
+ }
+
+ if (server.isActive()) {
+ String message = "Utils::waitReady: JMX connector server came up";
+ if ( elapsed == 0) {
+ message += " immediately";
+ } else {
+ message += " after " + elapsed + " seconds";
+ }
+ message += " [" + server.getAddress() + "]";
+ Utils.debug(DEBUG_STANDARD, message);
+ } else {
+ String message = "Utils::waitReady: (ERROR) JMX connector" +
+ " server didn't come up after " + elapsed + " seconds [" +
+ server.getAddress() + "]";
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ }
+
+ /**
+ * This method is used to compare the specified Throwable and possibly
+ * the derived causes to the specified String argument.
+ * The expected String argument format is :
+ * throwable_1;throwable_2;...;throwable_N
+ * where throwable_i can be :
+ * - either a throwable class name
+ * - or the "*" character meaning several unknown throwable class names
+ * This character must be followed by a throwable class name
+ */
+ static boolean compareThrowable(
+ Throwable t,
+ String expectedThrowable) {
+
+ // First parse the expectedThrowable String
+ StringTokenizer tokenizer = new StringTokenizer(expectedThrowable, ";");
+ String token = null;
+
+ try {
+ while (tokenizer.hasMoreTokens()) {
+ token = tokenizer.nextToken();
+ if (!token.equals("*")) {
+ if (!Class.forName(token).isInstance(t)) {
+ return false;
+ }
+ } else {
+ token = tokenizer.nextToken();
+ while (!Class.forName(token).isInstance(t)) {
+ t = t.getCause();
+ if (t == null) {
+ return false;
+ }
+ }
+ }
+ t = t.getCause();
+ }
+ } catch (ClassNotFoundException cnfe) {
+ String msg = "Expected throwable class(es) " + expectedThrowable +
+ " cannot be located";
+ System.out.println(msg);
+ throw new IllegalArgumentException(msg);
+ }
+ return true;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/security/access.properties Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,11 @@
+# Access control file for SQE tests.
+
+# Default username
+SQE_username readwrite create Simple
+
+# Functional authorization tests
+username1 readwrite create Simple
+username2 readonly
+username3 readonly
+username4 readwrite create Simple
+username5 readwrite create Simple
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/security/java.policy.authorization Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,98 @@
+// Standard extensions get all permissions by default
+
+grant codeBase "file:${java.home}/lib/ext/*" {
+ permission java.security.AllPermission;
+};
+
+// default permissions granted to all domains
+grant {
+ // Allows any thread to stop itself using the java.lang.Thread.stop()
+ // method that takes no argument.
+ // Note that this permission is granted by default only to remain
+ // backwards compatible.
+ // It is strongly recommended that you either remove this permission
+ // from this policy file or further restrict it to code sources
+ // that you specify, because Thread.stop() is potentially unsafe.
+ // See "http://java.sun.com/notes" for more information.
+ permission java.lang.RuntimePermission "stopThread";
+
+ // allows anyone to listen on un-privileged ports
+ permission java.net.SocketPermission "localhost:1024-", "listen";
+
+ // "standard" properies that can be read by anyone
+
+ permission java.util.PropertyPermission "java.version", "read";
+ permission java.util.PropertyPermission "java.vendor", "read";
+ permission java.util.PropertyPermission "java.vendor.url", "read";
+ permission java.util.PropertyPermission "java.class.version", "read";
+ permission java.util.PropertyPermission "os.name", "read";
+ permission java.util.PropertyPermission "os.version", "read";
+ permission java.util.PropertyPermission "os.arch", "read";
+ permission java.util.PropertyPermission "file.separator", "read";
+ permission java.util.PropertyPermission "path.separator", "read";
+ permission java.util.PropertyPermission "line.separator", "read";
+
+ permission java.util.PropertyPermission "java.specification.version", "read";
+ permission java.util.PropertyPermission "java.specification.vendor", "read";
+ permission java.util.PropertyPermission "java.specification.name", "read";
+
+ permission java.util.PropertyPermission "java.vm.specification.version", "read";
+ permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
+ permission java.util.PropertyPermission "java.vm.specification.name", "read";
+ permission java.util.PropertyPermission "java.vm.version", "read";
+ permission java.util.PropertyPermission "java.vm.vendor", "read";
+ permission java.util.PropertyPermission "java.vm.name", "read";
+
+ permission java.io.FilePermission "*","read,write";
+
+};
+
+grant codeBase "file:/-" {
+ permission java.security.AllPermission;
+ permission java.io.FilePermission "*","read,write";
+};
+
+grant principal javax.management.remote.JMXPrincipal "SQE_username" {
+ permission javax.management.MBeanServerPermission "*";
+ permission javax.management.MBeanPermission "Simple", "instantiate";
+ permission javax.management.MBeanPermission "Simple", "registerMBean";
+};
+
+grant principal javax.management.remote.JMXPrincipal "username1" {
+ //
+ // JMXPrincipals "username1" has all permissions.
+ //
+ permission java.security.AllPermission;
+};
+
+grant principal javax.management.remote.JMXPrincipal "username2" {
+ //
+ // JMXPrincipals "username2" has all permissions.
+ //
+ permission java.security.AllPermission;
+};
+
+grant principal javax.management.remote.JMXPrincipal "username3" {
+ //
+ // JMXPrincipals "username3" has some permissions.
+ //
+ permission javax.management.MBeanPermission "Simple", "instantiate";
+ permission javax.management.MBeanPermission "Simple", "registerMBean";
+ permission javax.management.MBeanPermission "Simple", "setAttribute";
+ permission javax.management.MBeanPermission "Simple", "invoke";
+};
+
+grant principal javax.management.remote.JMXPrincipal "username4" {
+ //
+ // JMXPrincipals "username4" has all permissions.
+ //
+ permission javax.management.MBeanPermission "Simple", "instantiate";
+ permission javax.management.MBeanPermission "Simple", "registerMBean";
+ permission javax.management.MBeanPermission "Simple", "invoke";
+};
+
+grant principal javax.management.remote.JMXPrincipal "username5" {
+ //
+ // JMXPrincipals "username5" has no permissions.
+ //
+};
Binary file jdk/test/javax/management/security/keystoreAgent has changed
Binary file jdk/test/javax/management/security/keystoreClient has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/security/login.config Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,8 @@
+PasswordFileAuthentication {
+ com.sun.jmx.remote.security.FileLoginModule required
+ passwordFile="${password.file}";
+};
+
+SampleLoginModule {
+ TestSampleLoginModule required;
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/security/password.properties Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,12 @@
+# Password file for default SQE username.
+SQE_username SQE_password
+
+# Functional authorization tests
+username1 password1
+username2 password2
+username3 password3
+username4 password4
+username5 password5
+username6 password6
+
+usernameFileLoginModule passwordFileLoginModule
Binary file jdk/test/javax/management/security/truststoreAgent has changed
Binary file jdk/test/javax/management/security/truststoreClient has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLSv12/SignatureAlgorithms.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,592 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
+/*
+ * @test
+ * @bug 8049321
+ * @summary Support SHA256WithDSA in JSSE
+ * @run main/othervm SignatureAlgorithms PKIX "SHA-224,SHA-256"
+ * TLS_DHE_DSS_WITH_AES_128_CBC_SHA
+ * @run main/othervm SignatureAlgorithms PKIX "SHA-1,SHA-224"
+ * TLS_DHE_DSS_WITH_AES_128_CBC_SHA
+ * @run main/othervm SignatureAlgorithms PKIX "SHA-1,SHA-256"
+ * TLS_DHE_DSS_WITH_AES_128_CBC_SHA
+ * @run main/othervm SignatureAlgorithms PKIX "SHA-224,SHA-256"
+ * TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
+ * @run main/othervm SignatureAlgorithms PKIX "SHA-1,SHA-224"
+ * TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
+ * @run main/othervm SignatureAlgorithms PKIX "SHA-1,SHA-256"
+ * TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
+ */
+
+import java.net.*;
+import java.util.*;
+import java.io.*;
+import javax.net.ssl.*;
+import java.security.Security;
+import java.security.KeyStore;
+import java.security.KeyFactory;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.spec.*;
+import java.security.interfaces.*;
+
+public class SignatureAlgorithms {
+
+ /*
+ * =============================================================
+ * Set the various variables needed for the tests, then
+ * specify what tests to run on each side.
+ */
+
+ /*
+ * Should we run the client or server in a separate thread?
+ * Both sides can throw exceptions, but do you have a preference
+ * as to which side should be the main thread.
+ */
+ static boolean separateServerThread = true;
+
+ /*
+ * Where do we find the keystores?
+ */
+ // Certificates and key (DSA) used in the test.
+ static String trustedCertStr =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIIDYTCCAyGgAwIBAgIJAK8/gw6zg/DPMAkGByqGSM44BAMwOzELMAkGA1UEBhMC\n" +
+ "VVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNl\n" +
+ "MB4XDTE1MTIwMzEzNTIyNVoXDTM2MTExMjEzNTIyNVowOzELMAkGA1UEBhMCVVMx\n" +
+ "DTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNlMIIB\n" +
+ "uDCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG4X+uxu5V\n" +
+ "b3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2eBfUv/hJ\n" +
+ "cLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNAqAB9PO5Y\n" +
+ "zKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAaor8iURd82\n" +
+ "b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I81drnN0Y\n" +
+ "lyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVXW+SEGADC\n" +
+ "J1+z8uqP3lIB6ltdgOiV/GQDgYUAAoGBAOXRppuJSGdt6AiZkb81P1DCUgIUlZFI\n" +
+ "J9GxWrjbbHDmGllMwPNhK6dU7LJKJJuYVPW+95rUGlSJEjRqSlHuyHkNb6e3e7qx\n" +
+ "tmx1/oIyq+oLult50hBS7uBvLLR0JbIKjBzzkudL8Rjze4G/Wq7KDM2T1JOP49tW\n" +
+ "eocCvaC8h8uQo4GtMIGqMB0GA1UdDgQWBBT17HcqLllsqnZzP+kElcGcBGmubjBr\n" +
+ "BgNVHSMEZDBigBT17HcqLllsqnZzP+kElcGcBGmubqE/pD0wOzELMAkGA1UEBhMC\n" +
+ "VVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNl\n" +
+ "ggkArz+DDrOD8M8wDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwCQYHKoZI\n" +
+ "zjgEAwMvADAsAhQ6Y1I6LtIEBMqNo8o6GIe4LLEJuwIUbVQUKi8tvtWyRoxm8AFV\n" +
+ "0axJYUU=\n" +
+ "-----END CERTIFICATE-----";
+
+ static String[] targetCertStr = {
+ // DSA-SHA1
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIIDKTCCAumgAwIBAgIJAOy5c0b+8stFMAkGByqGSM44BAMwOzELMAkGA1UEBhMC\n" +
+ "VVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNl\n" +
+ "MB4XDTE1MTIwMzEzNTIyNVoXDTM1MDgyMDEzNTIyNVowTzELMAkGA1UEBhMCVVMx\n" +
+ "DTALBgNVBAoMBEphdmExHTAbBgNVBAsMFFN1bkpTU0UgVGVzdCBTZXJpdmNlMRIw\n" +
+ "EAYDVQQDDAlsb2NhbGhvc3QwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEA8f5v4ZIx\n" +
+ "fopLuNcNF6/NzjrgMUbhf67G7lVvdTjKGxTwDxy4fiDCKfov8gOSZlDs3TMLSNGy\n" +
+ "IZVIywURNOrXQXf2kfZ4F9S/+Elwt8GciMES1WpX90TErzwe6XaxniZCKFDiKyw+\n" +
+ "XuGyuhL0RZiJydfSg0CoAH087ljMpt+kvtMCFQDXdZbjyuWfZQ/8toCC2fMqGpw2\n" +
+ "0wKBgQDdG/QaKtNsBqivyJRF3zZvkWUNN684JO6rtkil9lVXfSd5LtwFg163qb/f\n" +
+ "/hx9SVtuuqFuognYj4jzV2uc3RiXI3gqS7ERwHo5PB9aQhSPqu89oJCsEfxDbXds\n" +
+ "Orcce1g1o/w6h5BTJVdb5IQYAMInX7Py6o/eUgHqW12A6JX8ZAOBhAACgYB+zYqn\n" +
+ "jJwG4GZpBIN/6qhzbp0flChsV+Trlu0SL0agAQzb6XdI/4JnO87Pgbxaxh3VNAj3\n" +
+ "3+Ghr1NLBuBfTKzJ4j9msWT3EpLupkMyNtXvBYM0iyMrll67lSjMdv++wLEw35Af\n" +
+ "/bzVcjGyA5Q0i0cuEzDmHTVfi0OydynbwSLxtKNjMGEwCwYDVR0PBAQDAgPoMB0G\n" +
+ "A1UdDgQWBBQXJI8AxM0qsYCbbkIMuI5zJ+nMEDAfBgNVHSMEGDAWgBT17HcqLlls\n" +
+ "qnZzP+kElcGcBGmubjASBgNVHREBAf8ECDAGhwR/AAABMAkGByqGSM44BAMDLwAw\n" +
+ "LAIUXgyJ0xll4FrZAKXi8bj7Kiz+SA4CFH9WCSZIBYA9lmJkiTgRS7iM/6IC\n" +
+ "-----END CERTIFICATE-----",
+
+ // DSA-SHA224
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIIDLzCCAuugAwIBAgIJAOy5c0b+8stGMAsGCWCGSAFlAwQDATA7MQswCQYDVQQG\n" +
+ "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
+ "Y2UwHhcNMTUxMjAzMTU0NDM5WhcNMzUwODIwMTU0NDM5WjBPMQswCQYDVQQGEwJV\n" +
+ "UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Ux\n" +
+ "EjAQBgNVBAMMCWxvY2FsaG9zdDCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQDx/m/h\n" +
+ "kjF+iku41w0Xr83OOuAxRuF/rsbuVW91OMobFPAPHLh+IMIp+i/yA5JmUOzdMwtI\n" +
+ "0bIhlUjLBRE06tdBd/aR9ngX1L/4SXC3wZyIwRLValf3RMSvPB7pdrGeJkIoUOIr\n" +
+ "LD5e4bK6EvRFmInJ19KDQKgAfTzuWMym36S+0wIVANd1luPK5Z9lD/y2gILZ8yoa\n" +
+ "nDbTAoGBAN0b9Boq02wGqK/IlEXfNm+RZQ03rzgk7qu2SKX2VVd9J3ku3AWDXrep\n" +
+ "v9/+HH1JW266oW6iCdiPiPNXa5zdGJcjeCpLsRHAejk8H1pCFI+q7z2gkKwR/ENt\n" +
+ "d2w6txx7WDWj/DqHkFMlV1vkhBgAwidfs/Lqj95SAepbXYDolfxkA4GEAAKBgA81\n" +
+ "CJKEv+pwiqYgxtw/9rkQ9748WP3mKrEC06kjUG+94/Z9dQloNFFfj6LiO1bymc5l\n" +
+ "6QIR8XCi4Po3N80K3+WxhBGFhY+RkVWTh43JV8epb41aH2qiWErarBwBGEh8LyGT\n" +
+ "i30db+Nkz2gfvyz9H/9T0jmYgfLEOlMCusali1qHo2MwYTALBgNVHQ8EBAMCA+gw\n" +
+ "HQYDVR0OBBYEFBqSP0S4+X+zOCTEnlp2hbAjV/W5MB8GA1UdIwQYMBaAFPXsdyou\n" +
+ "WWyqdnM/6QSVwZwEaa5uMBIGA1UdEQEB/wQIMAaHBH8AAAEwCwYJYIZIAWUDBAMB\n" +
+ "AzEAMC4CFQChiRaOnAnsCSJFwdpK22jSxU/mhQIVALgLbj/G39+1Ej8UuSWnEQyU\n" +
+ "4DA+\n" +
+ "-----END CERTIFICATE-----",
+
+ // DSA-SHA256
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIIDLTCCAuugAwIBAgIJAOy5c0b+8stHMAsGCWCGSAFlAwQDAjA7MQswCQYDVQQG\n" +
+ "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
+ "Y2UwHhcNMTUxMjAzMTU0NjUxWhcNMzUwODIwMTU0NjUxWjBPMQswCQYDVQQGEwJV\n" +
+ "UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Ux\n" +
+ "EjAQBgNVBAMMCWxvY2FsaG9zdDCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQDx/m/h\n" +
+ "kjF+iku41w0Xr83OOuAxRuF/rsbuVW91OMobFPAPHLh+IMIp+i/yA5JmUOzdMwtI\n" +
+ "0bIhlUjLBRE06tdBd/aR9ngX1L/4SXC3wZyIwRLValf3RMSvPB7pdrGeJkIoUOIr\n" +
+ "LD5e4bK6EvRFmInJ19KDQKgAfTzuWMym36S+0wIVANd1luPK5Z9lD/y2gILZ8yoa\n" +
+ "nDbTAoGBAN0b9Boq02wGqK/IlEXfNm+RZQ03rzgk7qu2SKX2VVd9J3ku3AWDXrep\n" +
+ "v9/+HH1JW266oW6iCdiPiPNXa5zdGJcjeCpLsRHAejk8H1pCFI+q7z2gkKwR/ENt\n" +
+ "d2w6txx7WDWj/DqHkFMlV1vkhBgAwidfs/Lqj95SAepbXYDolfxkA4GEAAKBgEF7\n" +
+ "2qiYxGrjX4KCOy0k5nK/RYlgLy4gYDChihQpiaa+fbA5JOBOxPWsh7rdtmJuDrEJ\n" +
+ "keacU223+DIhOKC49fa+EvhLNqo6U1oPn8n/yvBsvvnWkcynw5KfNzaLlaPmzugh\n" +
+ "v9xl/GhyZNAXc1QUcW3C+ceHVNrKnkfbTKZz5eRSo2MwYTALBgNVHQ8EBAMCA+gw\n" +
+ "HQYDVR0OBBYEFNMkPrt40oO9Dpy+bcbQdEvOlNlyMB8GA1UdIwQYMBaAFPXsdyou\n" +
+ "WWyqdnM/6QSVwZwEaa5uMBIGA1UdEQEB/wQIMAaHBH8AAAEwCwYJYIZIAWUDBAMC\n" +
+ "Ay8AMCwCFCvA2QiKSe/n+6GqSYQwgQ/zL5M9AhQfSiuWdMJKWpgPJKakvzhBUbMb\n" +
+ "vA==\n" +
+ "-----END CERTIFICATE-----"};
+
+ // Private key in the format of PKCS#8, key size is 1024 bits.
+ static String[] targetPrivateKey = {
+ // For cert DSA-SHA1
+ "MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG\n" +
+ "4X+uxu5Vb3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2\n" +
+ "eBfUv/hJcLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNA\n" +
+ "qAB9PO5YzKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAao\n" +
+ "r8iURd82b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I\n" +
+ "81drnN0YlyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVX\n" +
+ "W+SEGADCJ1+z8uqP3lIB6ltdgOiV/GQEFgIUOiB7J/lrFrNduQ8nDNTe8VspoAI=",
+
+ // For cert DSA-SHA224
+ "MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG\n" +
+ "4X+uxu5Vb3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2\n" +
+ "eBfUv/hJcLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNA\n" +
+ "qAB9PO5YzKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAao\n" +
+ "r8iURd82b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I\n" +
+ "81drnN0YlyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVX\n" +
+ "W+SEGADCJ1+z8uqP3lIB6ltdgOiV/GQEFgIUOj9F5mxWd9W1tiLSdsOAt8BUBzE=",
+
+ // For cert DSA-SHA256
+ "MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG\n" +
+ "4X+uxu5Vb3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2\n" +
+ "eBfUv/hJcLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNA\n" +
+ "qAB9PO5YzKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAao\n" +
+ "r8iURd82b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I\n" +
+ "81drnN0YlyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVX\n" +
+ "W+SEGADCJ1+z8uqP3lIB6ltdgOiV/GQEFgIUQ2WGgg+OO39Aujj0e4lM4pP4/9g="};
+
+
+ static char passphrase[] = "passphrase".toCharArray();
+
+ /*
+ * Turn on SSL debugging?
+ */
+ static boolean debug = false;
+
+ /*
+ * Is the server ready to serve?
+ */
+ volatile boolean serverReady = false;
+
+ /*
+ * Define the server side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ void doServerSide() throws Exception {
+
+ SSLContext context = generateSSLContext(
+ null, targetCertStr, targetPrivateKey);
+ SSLServerSocketFactory sslssf = context.getServerSocketFactory();
+ try (SSLServerSocket sslServerSocket =
+ (SSLServerSocket)sslssf.createServerSocket(serverPort)) {
+
+ serverPort = sslServerSocket.getLocalPort();
+
+ /*
+ * Signal Client, we're ready for his connect.
+ */
+ serverReady = true;
+
+ try (SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept()) {
+ sslSocket.setEnabledCipherSuites(
+ sslSocket.getSupportedCipherSuites());
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslIS.read();
+ sslOS.write('A');
+ sslOS.flush();
+
+ dumpSignatureAlgorithms(sslSocket);
+ }
+ }
+ }
+
+ /*
+ * Define the client side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ void doClientSide() throws Exception {
+
+ /*
+ * Wait for server to get started.
+ */
+ while (!serverReady) {
+ Thread.sleep(50);
+ }
+
+ SSLContext context = generateSSLContext(trustedCertStr, null, null);
+ SSLSocketFactory sslsf = context.getSocketFactory();
+
+ try (SSLSocket sslSocket =
+ (SSLSocket)sslsf.createSocket("localhost", serverPort)) {
+
+ // enable TLSv1.2 only
+ sslSocket.setEnabledProtocols(new String[] {"TLSv1.2"});
+
+ // enable a block cipher
+ sslSocket.setEnabledCipherSuites(new String[] {cipherSuite});
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslOS.write('B');
+ sslOS.flush();
+ sslIS.read();
+
+ dumpSignatureAlgorithms(sslSocket);
+ }
+ }
+
+ static void dumpSignatureAlgorithms(SSLSocket sslSocket) throws Exception {
+
+ boolean isClient = sslSocket.getUseClientMode();
+ String mode = "[" + (isClient ? "Client" : "Server") + "]";
+ ExtendedSSLSession session =
+ (ExtendedSSLSession)sslSocket.getSession();
+ String[] signAlgs = session.getLocalSupportedSignatureAlgorithms();
+ System.out.println(
+ mode + " local supported signature algorithms: " +
+ Arrays.asList(signAlgs));
+
+ if (!isClient) {
+ signAlgs = session.getPeerSupportedSignatureAlgorithms();
+ System.out.println(
+ mode + " peer supported signature algorithms: " +
+ Arrays.asList(signAlgs));
+ } else {
+ Certificate[] serverCerts = session.getPeerCertificates();
+
+ // server should always send the authentication cert.
+ String sigAlg = ((X509Certificate)serverCerts[0]).getSigAlgName();
+ System.out.println(
+ mode + " the signature algorithm of server certificate: " +
+ sigAlg);
+ if (sigAlg.contains("SHA1")) {
+ if (disabledAlgorithms.contains("SHA-1")) {
+ throw new Exception(
+ "Not the expected server certificate. " +
+ "SHA-1 should be disabled");
+ }
+ } else if (sigAlg.contains("SHA224")) {
+ if (disabledAlgorithms.contains("SHA-224")) {
+ throw new Exception(
+ "Not the expected server certificate. " +
+ "SHA-224 should be disabled");
+ }
+ } else { // SHA-256
+ if (disabledAlgorithms.contains("SHA-256")) {
+ throw new Exception(
+ "Not the expected server certificate. " +
+ "SHA-256 should be disabled");
+ }
+ }
+ }
+ }
+
+ /*
+ * =============================================================
+ * The remainder is just support stuff
+ */
+ private static String tmAlgorithm; // trust manager
+ private static String disabledAlgorithms; // disabled algorithms
+ private static String cipherSuite; // cipher suite
+
+ private static void parseArguments(String[] args) {
+ tmAlgorithm = args[0];
+ disabledAlgorithms = args[1];
+ cipherSuite = args[2];
+ }
+
+ private static SSLContext generateSSLContext(String trustedCertStr,
+ String[] keyCertStrs, String[] keySpecStrs) throws Exception {
+
+ // generate certificate from cert string
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+
+ // create a key store
+ KeyStore ks = KeyStore.getInstance("JKS");
+ ks.load(null, null);
+
+ // import the trused cert
+ Certificate trusedCert = null;
+ ByteArrayInputStream is = null;
+ if (trustedCertStr != null) {
+ is = new ByteArrayInputStream(trustedCertStr.getBytes());
+ trusedCert = cf.generateCertificate(is);
+ is.close();
+
+ ks.setCertificateEntry("DSA Signer", trusedCert);
+ }
+
+ if (keyCertStrs != null && keyCertStrs.length != 0) {
+ for (int i = 0; i < keyCertStrs.length; i++) {
+ String keyCertStr = keyCertStrs[i];
+ String keySpecStr = keySpecStrs[i];
+
+ // generate the private key.
+ PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
+ Base64.getMimeDecoder().decode(keySpecStr));
+ KeyFactory kf = KeyFactory.getInstance("DSA");
+ DSAPrivateKey priKey =
+ (DSAPrivateKey)kf.generatePrivate(priKeySpec);
+
+ // generate certificate chain
+ is = new ByteArrayInputStream(keyCertStr.getBytes());
+ Certificate keyCert = cf.generateCertificate(is);
+ is.close();
+
+ Certificate[] chain = null;
+ if (trusedCert != null) {
+ chain = new Certificate[2];
+ chain[0] = keyCert;
+ chain[1] = trusedCert;
+ } else {
+ chain = new Certificate[1];
+ chain[0] = keyCert;
+ }
+
+ // import the key entry.
+ ks.setKeyEntry("DSA Entry " + i, priKey, passphrase, chain);
+ }
+ }
+
+ // create SSL context
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm);
+ tmf.init(ks);
+
+ SSLContext ctx = SSLContext.getInstance("TLS");
+ if (keyCertStrs != null && keyCertStrs.length != 0) {
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
+ kmf.init(ks, passphrase);
+
+ ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+ ks = null;
+ } else {
+ ctx.init(null, tmf.getTrustManagers(), null);
+ }
+
+ return ctx;
+ }
+
+
+ // use any free port by default
+ volatile int serverPort = 0;
+
+ volatile Exception serverException = null;
+ volatile Exception clientException = null;
+
+ public static void main(String[] args) throws Exception {
+ /*
+ * debug option
+ */
+ if (debug) {
+ System.setProperty("javax.net.debug", "all");
+ }
+
+ /*
+ * Get the customized arguments.
+ */
+ parseArguments(args);
+
+
+ /*
+ * Ignore testing on Windows if only SHA-224 is available.
+ */
+ if ((Security.getProvider("SunMSCAPI") != null) &&
+ (disabledAlgorithms.contains("SHA-1")) &&
+ (disabledAlgorithms.contains("SHA-256"))) {
+
+ System.out.println(
+ "Windows system does not support SHA-224 algorithms yet. " +
+ "Ignore the testing");
+
+ return;
+ }
+
+ /*
+ * Expose the target algorithms by diabling unexpected algorithms.
+ */
+ Security.setProperty(
+ "jdk.certpath.disabledAlgorithms", disabledAlgorithms);
+
+ /*
+ * Reset the security property to make sure that the algorithms
+ * and keys used in this test are not disabled by default.
+ */
+ Security.setProperty( "jdk.tls.disabledAlgorithms", "");
+
+ /*
+ * Start the tests.
+ */
+ new SignatureAlgorithms();
+ }
+
+ Thread clientThread = null;
+ Thread serverThread = null;
+
+ /*
+ * Primary constructor, used to drive remainder of the test.
+ *
+ * Fork off the other side, then do your work.
+ */
+ SignatureAlgorithms() throws Exception {
+ try {
+ if (separateServerThread) {
+ startServer(true);
+ startClient(false);
+ } else {
+ startClient(true);
+ startServer(false);
+ }
+ } catch (Exception e) {
+ // swallow for now. Show later
+ }
+
+ /*
+ * Wait for other side to close down.
+ */
+ if (separateServerThread) {
+ serverThread.join();
+ } else {
+ clientThread.join();
+ }
+
+ /*
+ * When we get here, the test is pretty much over.
+ * Which side threw the error?
+ */
+ Exception local;
+ Exception remote;
+ String whichRemote;
+
+ if (separateServerThread) {
+ remote = serverException;
+ local = clientException;
+ whichRemote = "server";
+ } else {
+ remote = clientException;
+ local = serverException;
+ whichRemote = "client";
+ }
+
+ /*
+ * If both failed, return the curthread's exception, but also
+ * print the remote side Exception
+ */
+ if ((local != null) && (remote != null)) {
+ System.out.println(whichRemote + " also threw:");
+ remote.printStackTrace();
+ System.out.println();
+ throw local;
+ }
+
+ if (remote != null) {
+ throw remote;
+ }
+
+ if (local != null) {
+ throw local;
+ }
+ }
+
+ void startServer(boolean newThread) throws Exception {
+ if (newThread) {
+ serverThread = new Thread() {
+ public void run() {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ /*
+ * Our server thread just died.
+ *
+ * Release the client, if not active already...
+ */
+ System.err.println("Server died..." + e);
+ serverReady = true;
+ serverException = e;
+ }
+ }
+ };
+ serverThread.start();
+ } else {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ serverException = e;
+ } finally {
+ serverReady = true;
+ }
+ }
+ }
+
+ void startClient(boolean newThread) throws Exception {
+ if (newThread) {
+ clientThread = new Thread() {
+ public void run() {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ /*
+ * Our client thread just died.
+ */
+ System.err.println("Client died..." + e);
+ clientException = e;
+ }
+ }
+ };
+ clientThread.start();
+ } else {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ clientException = e;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/nio/zipfs/MultiReleaseJarTest.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8144355
+ * @summary Test aliasing additions to ZipFileSystem for multi-release jar files
+ * @library /lib/testlibrary/java/util/jar
+ * @build Compiler JarBuilder CreateMultiReleaseTestJars
+ * @run testng MultiReleaseJarTest
+ */
+
+import java.io.IOException;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.net.URI;
+import java.nio.file.*;
+import java.util.HashMap;
+import java.util.Map;
+
+import static sun.misc.Version.jdkMajorVersion;
+
+import org.testng.Assert;
+import org.testng.annotations.*;
+
+public class MultiReleaseJarTest {
+ final private String userdir = System.getProperty("user.dir",".");
+ final private Map<String,String> stringEnv = new HashMap<>();
+ final private Map<String,Integer> integerEnv = new HashMap<>();
+ final private String className = "version.Version";
+ final private MethodType mt = MethodType.methodType(int.class);
+
+ private String entryName;
+ private URI uvuri;
+ private URI mruri;
+ private URI smruri;
+
+ @BeforeClass
+ public void initialize() throws Exception {
+ CreateMultiReleaseTestJars creator = new CreateMultiReleaseTestJars();
+ creator.compileEntries();
+ creator.buildUnversionedJar();
+ creator.buildMultiReleaseJar();
+ creator.buildShortMultiReleaseJar();
+ String ssp = Paths.get(userdir, "unversioned.jar").toUri().toString();
+ uvuri = new URI("jar", ssp , null);
+ ssp = Paths.get(userdir, "multi-release.jar").toUri().toString();
+ mruri = new URI("jar", ssp, null);
+ ssp = Paths.get(userdir, "short-multi-release.jar").toUri().toString();
+ smruri = new URI("jar", ssp, null);
+ entryName = className.replace('.', '/') + ".class";
+ }
+
+ public void close() throws IOException {
+ Files.delete(Paths.get(userdir, "unversioned.jar"));
+ Files.delete(Paths.get(userdir, "multi-release.jar"));
+ Files.delete(Paths.get(userdir, "short-multi-release.jar"));
+ }
+
+ @DataProvider(name="strings")
+ public Object[][] createStrings() {
+ return new Object[][]{
+ {"runtime", jdkMajorVersion()},
+ {"-20", 8},
+ {"0", 8},
+ {"8", 8},
+ {"9", 9},
+ {"10", 10},
+ {"11", 10},
+ {"50", 10}
+ };
+ }
+
+ @DataProvider(name="integers")
+ public Object[][] createIntegers() {
+ return new Object[][] {
+ {new Integer(-5), 8},
+ {new Integer(0), 8},
+ {new Integer(8), 8},
+ {new Integer(9), 9},
+ {new Integer(10), 10},
+ {new Integer(11), 10},
+ {new Integer(100), 10}
+ };
+ }
+
+ // Not the best test but all I can do since ZipFileSystem and JarFileSystem
+ // are not public, so I can't use (fs instanceof ...)
+ @Test
+ public void testNewFileSystem() throws Exception {
+ Map<String,String> env = new HashMap<>();
+ // no configuration, treat multi-release jar as unversioned
+ try (FileSystem fs = FileSystems.newFileSystem(mruri, env)) {
+ Assert.assertTrue(readAndCompare(fs, 8));
+ }
+ env.put("multi-release", "runtime");
+ // a configuration and jar file is multi-release
+ try (FileSystem fs = FileSystems.newFileSystem(mruri, env)) {
+ Assert.assertTrue(readAndCompare(fs, jdkMajorVersion()));
+ }
+ // a configuration but jar file is unversioned
+ try (FileSystem fs = FileSystems.newFileSystem(uvuri, env)) {
+ Assert.assertTrue(readAndCompare(fs, 8));
+ }
+ }
+
+ private boolean readAndCompare(FileSystem fs, int expected) throws IOException {
+ Path path = fs.getPath("version/Version.java");
+ String src = new String(Files.readAllBytes(path));
+ return src.contains("return " + expected);
+ }
+
+ @Test(dataProvider="strings")
+ public void testStrings(String value, int expected) throws Throwable {
+ stringEnv.put("multi-release", value);
+ runTest(stringEnv, expected);
+ }
+
+ @Test(dataProvider="integers")
+ public void testIntegers(Integer value, int expected) throws Throwable {
+ integerEnv.put("multi-release", value);
+ runTest(integerEnv, expected);
+ }
+
+ @Test
+ public void testShortJar() throws Throwable {
+ integerEnv.put("multi-release", Integer.valueOf(10));
+ runTest(smruri, integerEnv, 10);
+ integerEnv.put("multi-release", Integer.valueOf(9));
+ runTest(smruri, integerEnv, 8);
+ }
+
+ private void runTest(Map<String,?> env, int expected) throws Throwable {
+ runTest(mruri, env, expected);
+ }
+
+ private void runTest(URI uri, Map<String,?> env, int expected) throws Throwable {
+ try (FileSystem fs = FileSystems.newFileSystem(uri, env)) {
+ Path version = fs.getPath(entryName);
+ byte [] bytes = Files.readAllBytes(version);
+ Class<?> vcls = (new ByteArrayClassLoader(fs)).defineClass(className, bytes);
+ MethodHandle mh = MethodHandles.lookup().findVirtual(vcls, "getVersion", mt);
+ Assert.assertEquals((int)mh.invoke(vcls.newInstance()), expected);
+ }
+ }
+
+ private static class ByteArrayClassLoader extends ClassLoader {
+ final private FileSystem fs;
+
+ ByteArrayClassLoader(FileSystem fs) {
+ super(null);
+ this.fs = fs;
+ }
+
+ @Override
+ public Class<?> loadClass(String name) throws ClassNotFoundException {
+ try {
+ return super.loadClass(name);
+ } catch (ClassNotFoundException x) {}
+ Path cls = fs.getPath(name.replace('.', '/') + ".class");
+ try {
+ byte[] bytes = Files.readAllBytes(cls);
+ return defineClass(name, bytes);
+ } catch (IOException x) {
+ throw new ClassNotFoundException(x.getMessage());
+ }
+ }
+
+ public Class<?> defineClass(String name, byte[] bytes) throws ClassNotFoundException {
+ if (bytes == null) throw new ClassNotFoundException("No bytes for " + name);
+ return defineClass(name, bytes, 0, bytes.length);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/lib/testlibrary/java/util/jar/Compiler.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 javax.tools.*;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+class Compiler {
+ final private Map<String,String> input;
+ private List<String> options;
+
+ Compiler(Map<String,String> input) {
+ this.input = input;
+ }
+
+ Compiler setRelease(int release) {
+ // Setting the -release option does not work for some reason
+ // so do it the old fashioned way
+ // options = Arrays.asList("-release", String.valueOf(release));
+ String target = String.valueOf(release);
+ options = Arrays.asList("-source", target, "-target", target);
+ return this;
+ }
+
+ Map<String,byte[]> compile() {
+ List<SourceFileObject> cunits = createCompilationUnits();
+ Map<String,ClassFileObject> cfos = createClassFileObjects();
+ JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
+ JavaFileManager jfm = new CustomFileManager(jc.getStandardFileManager(null, null, null), cfos);
+ jc.getTask(null, jfm, null, options, null, cunits).call();
+ return createOutput(cfos);
+ }
+
+ private List<SourceFileObject> createCompilationUnits() {
+ return input.entrySet().stream()
+ .map(e -> new SourceFileObject(e.getKey(), e.getValue())).collect(Collectors.toList());
+ }
+
+ private Map<String,ClassFileObject> createClassFileObjects() {
+ return input.keySet().stream()
+ .collect(Collectors.toMap(k -> k, k -> new ClassFileObject(k)));
+ }
+
+ private Map<String,byte[]> createOutput(Map<String,ClassFileObject> cfos) {
+ return cfos.keySet().stream().collect(Collectors.toMap(k -> k, k -> cfos.get(k).getBytes()));
+ }
+
+ private static class SourceFileObject extends SimpleJavaFileObject {
+ private final String source;
+
+ SourceFileObject(String name, String source) {
+ super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
+ this.source = source;
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return source;
+ }
+ }
+
+ private static class ClassFileObject extends SimpleJavaFileObject {
+ private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ ClassFileObject(String className) {
+ super(URI.create(className), Kind.CLASS);
+ }
+
+ @Override
+ public OutputStream openOutputStream() throws IOException {
+ return baos;
+ }
+
+ public byte[] getBytes() {
+ return baos.toByteArray();
+ }
+ }
+
+ private static class CustomFileManager extends ForwardingJavaFileManager<JavaFileManager> {
+ private final Map<String,ClassFileObject> cfos;
+
+ CustomFileManager(JavaFileManager jfm, Map<String,ClassFileObject> cfos) {
+ super(jfm);
+ this.cfos = cfos;
+ }
+
+ @Override
+ public JavaFileObject getJavaFileForOutput(JavaFileManager.Location loc, String name,
+ JavaFileObject.Kind kind, FileObject sibling) throws IOException {
+ ClassFileObject cfo = cfos.get(name);
+ return cfo;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/lib/testlibrary/java/util/jar/CreateMultiReleaseTestJars.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Map;
+
+public class CreateMultiReleaseTestJars {
+ final private String main =
+ "package version;\n\n"
+ + "public class Main {\n"
+ + " public static void main(String[] args) {\n"
+ + " Version v = new Version();\n"
+ + " System.out.println(\"I am running on version \" + v.getVersion());\n"
+ + " }\n"
+ + "}\n";
+ final private String java8 =
+ "package version;\n\n"
+ + "public class Version {\n"
+ + " public int getVersion() {\n"
+ + " return 8;\n"
+ + " }\n"
+ + "}\n";
+ final private String java9 =
+ "package version;\n\n"
+ + "public class Version {\n"
+ + " public int getVersion() {\n"
+ + " int version = (new PackagePrivate()).getVersion();\n"
+ + " if (version == 9) return 9;\n" // strange I know, but easy to test
+ + " return version;\n"
+ + " }\n"
+ + "}\n";
+ final private String ppjava9 =
+ "package version;\n\n"
+ + "class PackagePrivate {\n"
+ + " int getVersion() {\n"
+ + " return 9;\n"
+ + " }\n"
+ + "}\n";
+ final private String java10 = java8.replace("8", "10");
+ final String readme8 = "This is the root readme file";
+ final String readme9 = "This is the version nine readme file";
+ final String readme10 = "This is the version ten readme file";
+ private Map<String,byte[]> rootClasses;
+ private Map<String,byte[]> version9Classes;
+ private Map<String,byte[]> version10Classes;
+
+ public void buildUnversionedJar() throws IOException {
+ JarBuilder jb = new JarBuilder("unversioned.jar");
+ jb.addEntry("README", readme8.getBytes());
+ jb.addEntry("version/Main.java", main.getBytes());
+ jb.addEntry("version/Main.class", rootClasses.get("version.Main"));
+ jb.addEntry("version/Version.java", java8.getBytes());
+ jb.addEntry("version/Version.class", rootClasses.get("version.Version"));
+ jb.build();
+ }
+
+ public void buildMultiReleaseJar() throws IOException {
+ JarBuilder jb = new JarBuilder("multi-release.jar");
+ jb.addAttribute("Multi-Release", "true");
+ jb.addEntry("README", readme8.getBytes());
+ jb.addEntry("version/Main.java", main.getBytes());
+ jb.addEntry("version/Main.class", rootClasses.get("version.Main"));
+ jb.addEntry("version/Version.java", java8.getBytes());
+ jb.addEntry("version/Version.class", rootClasses.get("version.Version"));
+ jb.addEntry("META-INF/versions/9/README", readme9.getBytes());
+ jb.addEntry("META-INF/versions/9/version/Version.java", java9.getBytes());
+ jb.addEntry("META-INF/versions/9/version/PackagePrivate.java", ppjava9.getBytes());
+ jb.addEntry("META-INF/versions/9/version/Version.class", version9Classes.get("version.Version"));
+ jb.addEntry("META-INF/versions/9/version/PackagePrivate.class", version9Classes.get("version.PackagePrivate"));
+ jb.addEntry("META-INF/versions/10/README", readme10.getBytes());
+ jb.addEntry("META-INF/versions/10/version/Version.java", java10.getBytes());
+ jb.addEntry("META-INF/versions/10/version/Version.class", version10Classes.get("version.Version"));
+ jb.build();
+ }
+
+ public void buildShortMultiReleaseJar() throws IOException {
+ JarBuilder jb = new JarBuilder("short-multi-release.jar");
+ jb.addAttribute("Multi-Release", "true");
+ jb.addEntry("README", readme8.getBytes());
+ jb.addEntry("version/Main.java", main.getBytes());
+ jb.addEntry("version/Main.class", rootClasses.get("version.Main"));
+ jb.addEntry("version/Version.java", java8.getBytes());
+ jb.addEntry("version/Version.class", rootClasses.get("version.Version"));
+ jb.addEntry("META-INF/versions/9/README", readme9.getBytes());
+ jb.addEntry("META-INF/versions/9/version/Version.java", java9.getBytes());
+ jb.addEntry("META-INF/versions/9/version/PackagePrivate.java", ppjava9.getBytes());
+ // no entry for META-INF/versions/9/version/Version.class
+ jb.addEntry("META-INF/versions/9/version/PackagePrivate.class", version9Classes.get("version.PackagePrivate"));
+ jb.addEntry("META-INF/versions/10/README", readme10.getBytes());
+ jb.addEntry("META-INF/versions/10/version/Version.java", java10.getBytes());
+ jb.addEntry("META-INF/versions/10/version/Version.class", version10Classes.get("version.Version"));
+ jb.build();
+ }
+
+ public void buildSignedMultiReleaseJar() throws Exception {
+ String testsrc = System.getProperty("test.src",".");
+ String testdir = findTestDir(testsrc);
+ String keystore = testdir + "/sun/security/tools/jarsigner/JarSigning.keystore";
+ String[] jsArgs = {
+ "-keystore", keystore,
+ "-storepass", "bbbbbb",
+ "-signedJar", "signed-multi-release.jar",
+ "multi-release.jar", "b"
+ };
+ sun.security.tools.jarsigner.Main.main(jsArgs);
+
+ }
+
+ String findTestDir(String dir) throws IOException {
+ Path path = Paths.get(dir).toAbsolutePath();
+ while (path != null && !path.endsWith("test")) {
+ path = path.getParent();
+ }
+ if (path == null) {
+ throw new IllegalArgumentException(dir + " is not in a test directory");
+ }
+ if (!Files.isDirectory(path)) {
+ throw new IOException(path.toString() + " is not a directory");
+ }
+ return path.toString();
+ }
+
+ void compileEntries() {
+ Map<String,String> input = new HashMap<>();
+ input.put("version.Main", main);
+ input.put("version.Version", java8);
+ rootClasses = (new Compiler(input)).setRelease(8).compile();
+ input.clear();
+ input.put("version.Version", java9);
+ input.put("version.PackagePrivate", ppjava9);
+ version9Classes = (new Compiler(input)).setRelease(9).compile();
+ input.clear();
+ input.put("version.Version", java10);
+ version10Classes = (new Compiler(input)).setRelease(9).compile(); // fixme in JDK 10
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/lib/testlibrary/java/util/jar/JarBuilder.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+public class JarBuilder {
+ final private String name;
+ final private Attributes attributes = new Attributes();
+ final private List<Entry> entries = new ArrayList<>();
+
+ public JarBuilder(String name) {
+ this.name = name;
+ attributes.putValue("Manifest-Version", "1.0");
+ attributes.putValue("Created-By", "1.9.0-internal (Oracle Corporation)");
+ }
+
+ public JarBuilder addAttribute(String name, String value) {
+ attributes.putValue(name, value);
+ return this;
+ }
+
+ public JarBuilder addEntry(String name, byte[] bytes) {
+ entries.add(new Entry(name, bytes));
+ return this;
+ }
+
+ public void build() throws IOException {
+ try (OutputStream os = Files.newOutputStream(Paths.get(name));
+ JarOutputStream jos = new JarOutputStream(os)) {
+ JarEntry me = new JarEntry("META-INF/MANIFEST.MF");
+ jos.putNextEntry(me);
+ Manifest manifest = new Manifest();
+ manifest.getMainAttributes().putAll(attributes);
+ manifest.write(jos);
+ jos.closeEntry();
+ entries.forEach(e -> {
+ JarEntry je = new JarEntry(e.name);
+ try {
+ jos.putNextEntry(je);
+ jos.write(e.bytes);
+ jos.closeEntry();
+ } catch (IOException iox) {
+ throw new RuntimeException(iox);
+ }
+ });
+ } catch (RuntimeException x) {
+ Throwable t = x.getCause();
+ if (t instanceof IOException) {
+ IOException iox = (IOException)t;
+ throw iox;
+ }
+ throw x;
+ }
+ }
+
+ private static class Entry {
+ String name;
+ byte[] bytes;
+
+ Entry(String name, byte[] bytes) {
+ this.name = name;
+ this.bytes = bytes;
+ }
+ }
+
+ public static void main(String[] args) throws IOException {
+ JarBuilder jb = new JarBuilder("version.jar");
+ jb.addAttribute("Multi-Release", "true");
+ String s = "something to say";
+ byte[] bytes = s.getBytes();
+ jb.addEntry("version/Version.class", bytes);
+ jb.addEntry("README", bytes);
+ jb.addEntry("version/Version.java", bytes);
+ jb.build();
+ }
+}
--- a/jdk/test/sun/security/pkcs11/rsa/TestKeyPairGenerator.java Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/rsa/TestKeyPairGenerator.java Tue Jan 05 10:38:10 2016 -0800
@@ -107,7 +107,7 @@
data = new byte[2048];
// keypair generation is very slow, test only a few short keys
int[] keyLengths = {512, 512, 1024};
- BigInteger[] pubExps = {null, BigInteger.valueOf(3), null};
+ BigInteger[] pubExps = {null, RSAKeyGenParameterSpec.F4, null};
KeyPair[] keyPairs = new KeyPair[3];
RandomFactory.getRandom().nextBytes(data);
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", provider);
--- a/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh Mon Jan 04 17:07:23 2016 -0800
+++ b/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh Tue Jan 05 10:38:10 2016 -0800
@@ -69,8 +69,8 @@
# First part: output format
# ==========================================================
-$KT -genkeypair -alias a1 -dname CN=a1 -validity 365
-$KT -genkeypair -alias a2 -dname CN=a2 -validity 365
+$KT -genkeypair -alias a1 -dname CN=a1 -validity 366
+$KT -genkeypair -alias a2 -dname CN=a2 -validity 366
# a.jar includes 8 unsigned, 2 signed by a1 and a2, 2 signed by a3
$JAR cvf a.jar A1.class A2.class
--- a/langtools/.hgtags Mon Jan 04 17:07:23 2016 -0800
+++ b/langtools/.hgtags Tue Jan 05 10:38:10 2016 -0800
@@ -341,3 +341,4 @@
d2a44416cba39957ea231eedc2fb8aad7be1b30c jdk-9+96
ae8cdc734bab4f19ef8babd2434dcf024672ad38 jdk-9+97
345520da2ec17100cb512a53d541a307a195305e jdk-9+98
+cb73b474703e2de266542b505cffd658bcc052da jdk-9+99
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java Mon Jan 04 17:07:23 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java Tue Jan 05 10:38:10 2016 -0800
@@ -25,6 +25,7 @@
package com.sun.tools.javac.comp;
+import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Scope.WriteableScope;
@@ -95,6 +96,13 @@
*/
Type defaultSuperCallSite = null;
+ /** Tree that when non null, is to be preferentially used in diagnostics.
+ * Usually Env<AttrContext>.tree is the tree to be referred to in messages,
+ * but this may not be true during the window a method is looked up in enclosing
+ * contexts (JDK-8145466)
+ */
+ JCTree preferredTreeForDiagnostics;
+
/** Duplicate this context, replacing scope field and copying all others.
*/
AttrContext dup(WriteableScope scope) {
@@ -112,6 +120,7 @@
info.isSpeculative = isSpeculative;
info.isAnonymousDiamond = isAnonymousDiamond;
info.isNewClass = isNewClass;
+ info.preferredTreeForDiagnostics = preferredTreeForDiagnostics;
return info;
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Mon Jan 04 17:07:23 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Tue Jan 05 10:38:10 2016 -0800
@@ -722,7 +722,8 @@
Warner warn) {
//should we expand formals?
boolean useVarargs = deferredAttrContext.phase.isVarargsRequired();
- List<JCExpression> trees = TreeInfo.args(env.tree);
+ JCTree callTree = treeForDiagnostics(env);
+ List<JCExpression> trees = TreeInfo.args(callTree);
//inference context used during this method check
InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
@@ -731,7 +732,7 @@
if (varargsFormal == null &&
argtypes.size() != formals.size()) {
- reportMC(env.tree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
+ reportMC(callTree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
}
while (argtypes.nonEmpty() && formals.head != varargsFormal) {
@@ -743,7 +744,7 @@
}
if (formals.head != varargsFormal) {
- reportMC(env.tree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
+ reportMC(callTree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
}
if (useVarargs) {
@@ -759,6 +760,11 @@
}
}
+ // where
+ private JCTree treeForDiagnostics(Env<AttrContext> env) {
+ return env.info.preferredTreeForDiagnostics != null ? env.info.preferredTreeForDiagnostics : env.tree;
+ }
+
/**
* Does the actual argument conforms to the corresponding formal?
*/
@@ -1847,17 +1853,23 @@
boolean staticOnly = false;
while (env1.outer != null) {
if (isStatic(env1)) staticOnly = true;
- Symbol sym = findMethod(
- env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
- allowBoxing, useVarargs);
- if (sym.exists()) {
- if (staticOnly &&
- sym.kind == MTH &&
- sym.owner.kind == TYP &&
- (sym.flags() & STATIC) == 0) return new StaticError(sym);
- else return sym;
- } else {
- bestSoFar = bestOf(bestSoFar, sym);
+ Assert.check(env1.info.preferredTreeForDiagnostics == null);
+ env1.info.preferredTreeForDiagnostics = env.tree;
+ try {
+ Symbol sym = findMethod(
+ env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
+ allowBoxing, useVarargs);
+ if (sym.exists()) {
+ if (staticOnly &&
+ sym.kind == MTH &&
+ sym.owner.kind == TYP &&
+ (sym.flags() & STATIC) == 0) return new StaticError(sym);
+ else return sym;
+ } else {
+ bestSoFar = bestOf(bestSoFar, sym);
+ }
+ } finally {
+ env1.info.preferredTreeForDiagnostics = null;
}
if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
env1 = env1.outer;
@@ -4184,7 +4196,11 @@
DiagnosticPosition preferedPos, DiagnosticSource preferredSource,
DiagnosticType preferredKind, JCDiagnostic d) {
JCDiagnostic cause = (JCDiagnostic)d.getArgs()[causeIndex];
- return diags.create(preferredKind, preferredSource, d.getDiagnosticPosition(),
+ DiagnosticPosition pos = d.getDiagnosticPosition();
+ if (pos == null) {
+ pos = preferedPos;
+ }
+ return diags.create(preferredKind, preferredSource, pos,
"prob.found.req", cause);
}
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java Mon Jan 04 17:07:23 2016 -0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java Tue Jan 05 10:38:10 2016 -0800
@@ -190,7 +190,7 @@
private List<SnippetEvent> processVariables(String userSource, List<? extends Tree> units, String compileSource, ParseTask pt) {
List<SnippetEvent> allEvents = new ArrayList<>();
- TreeDissector dis = new TreeDissector(pt);
+ TreeDissector dis = TreeDissector.createByFirstClass(pt);
for (Tree unitTree : units) {
VariableTree vt = (VariableTree) unitTree;
String name = vt.getName().toString();
@@ -295,7 +295,7 @@
TreeDependencyScanner tds = new TreeDependencyScanner();
tds.scan(unitTree);
- TreeDissector dis = new TreeDissector(pt);
+ TreeDissector dis = TreeDissector.createByFirstClass(pt);
ClassTree klassTree = (ClassTree) unitTree;
String name = klassTree.getSimpleName().toString();
@@ -354,7 +354,7 @@
tds.scan(unitTree);
MethodTree mt = (MethodTree) unitTree;
- TreeDissector dis = new TreeDissector(pt);
+ TreeDissector dis = TreeDissector.createByFirstClass(pt);
DiagList modDiag = modifierDiagnostics(mt.getModifiers(), dis, true);
if (modDiag.hasErrors()) {
return compileFailResult(modDiag, userSource);
@@ -418,8 +418,8 @@
private ExpressionInfo typeOfExpression(String expression) {
Wrap guts = Wrap.methodReturnWrap(expression);
TaskFactory.AnalyzeTask at = trialCompile(guts);
- if (!at.hasErrors() && at.cuTree() != null) {
- return new TreeDissector(at)
+ if (!at.hasErrors() && at.firstCuTree() != null) {
+ return TreeDissector.createByFirstClass(at)
.typeOfReturnStatement(at.messages(), state.maps::fullClassNameAndPackageToClass);
}
return null;
@@ -513,13 +513,17 @@
ins.stream().forEach(u -> u.initialize(ins));
AnalyzeTask at = state.taskFactory.new AnalyzeTask(ins);
ins.stream().forEach(u -> u.setDiagnostics(at));
+
// corral any Snippets that need it
- if (ins.stream().filter(u -> u.corralIfNeeded(ins)).count() > 0) {
+ AnalyzeTask cat;
+ if (ins.stream().anyMatch(u -> u.corralIfNeeded(ins))) {
// if any were corralled, re-analyze everything
- AnalyzeTask cat = state.taskFactory.new AnalyzeTask(ins);
+ cat = state.taskFactory.new AnalyzeTask(ins);
ins.stream().forEach(u -> u.setCorralledDiagnostics(cat));
+ } else {
+ cat = at;
}
- ins.stream().forEach(u -> u.setStatus());
+ ins.stream().forEach(u -> u.setStatus(cat));
// compile and load the legit snippets
boolean success;
while (true) {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Mon Jan 04 17:07:23 2016 -0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Tue Jan 05 10:38:10 2016 -0800
@@ -239,7 +239,7 @@
private List<Suggestion> computeSuggestions(OuterWrap code, int cursor, int[] anchor) {
AnalyzeTask at = proc.taskFactory.new AnalyzeTask(code);
SourcePositions sp = at.trees().getSourcePositions();
- CompilationUnitTree topLevel = at.cuTree();
+ CompilationUnitTree topLevel = at.firstCuTree();
List<Suggestion> result = new ArrayList<>();
TreePath tp = pathFor(topLevel, sp, code.snippetIndexToWrapIndex(cursor));
if (tp != null) {
@@ -976,7 +976,7 @@
OuterWrap codeWrap = wrapInClass(Wrap.methodWrap(code));
AnalyzeTask at = proc.taskFactory.new AnalyzeTask(codeWrap);
SourcePositions sp = at.trees().getSourcePositions();
- CompilationUnitTree topLevel = at.cuTree();
+ CompilationUnitTree topLevel = at.firstCuTree();
TreePath tp = pathFor(topLevel, sp, codeWrap.snippetIndexToWrapIndex(cursor));
if (tp == null)
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java Mon Jan 04 17:07:23 2016 -0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java Tue Jan 05 10:38:10 2016 -0800
@@ -56,6 +56,7 @@
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
+import static java.util.stream.Collectors.toList;
import java.util.stream.Stream;
import javax.lang.model.util.Elements;
import javax.tools.FileObject;
@@ -196,7 +197,7 @@
*/
class ParseTask extends BaseTask {
- private final CompilationUnitTree cut;
+ private final Iterable<? extends CompilationUnitTree> cuts;
private final List<? extends Tree> units;
ParseTask(final String source) {
@@ -204,16 +205,13 @@
new StringSourceHandler(),
"-XDallowStringFolding=false", "-proc:none");
ReplParserFactory.instance(getContext());
- Iterable<? extends CompilationUnitTree> asts = parse();
- Iterator<? extends CompilationUnitTree> it = asts.iterator();
- if (it.hasNext()) {
- this.cut = it.next();
- List<? extends ImportTree> imps = cut.getImports();
- this.units = !imps.isEmpty() ? imps : cut.getTypeDecls();
- } else {
- this.cut = null;
- this.units = Collections.emptyList();
- }
+ cuts = parse();
+ units = Util.stream(cuts)
+ .flatMap(cut -> {
+ List<? extends ImportTree> imps = cut.getImports();
+ return (!imps.isEmpty() ? imps : cut.getTypeDecls()).stream();
+ })
+ .collect(toList());
}
private Iterable<? extends CompilationUnitTree> parse() {
@@ -229,8 +227,8 @@
}
@Override
- CompilationUnitTree cuTree() {
- return cut;
+ Iterable<? extends CompilationUnitTree> cuTrees() {
+ return cuts;
}
}
@@ -239,7 +237,7 @@
*/
class AnalyzeTask extends BaseTask {
- private final CompilationUnitTree cut;
+ private final Iterable<? extends CompilationUnitTree> cuts;
AnalyzeTask(final OuterWrap wrap) {
this(Stream.of(wrap),
@@ -255,14 +253,7 @@
<T>AnalyzeTask(final Stream<T> stream, SourceHandler<T> sourceHandler,
String... extraOptions) {
super(stream, sourceHandler, extraOptions);
- Iterator<? extends CompilationUnitTree> cuts = analyze().iterator();
- if (cuts.hasNext()) {
- this.cut = cuts.next();
- //proc.debug("AnalyzeTask element=%s cutp=%s cut=%s\n", e, cutp, cut);
- } else {
- this.cut = null;
- //proc.debug("AnalyzeTask -- no elements -- %s\n", getDiagnostics());
- }
+ cuts = analyze();
}
private Iterable<? extends CompilationUnitTree> analyze() {
@@ -276,8 +267,8 @@
}
@Override
- CompilationUnitTree cuTree() {
- return cut;
+ Iterable<? extends CompilationUnitTree> cuTrees() {
+ return cuts;
}
Elements getElements() {
@@ -332,7 +323,7 @@
}
@Override
- CompilationUnitTree cuTree() {
+ Iterable<? extends CompilationUnitTree> cuTrees() {
throw new UnsupportedOperationException("Not supported.");
}
}
@@ -362,7 +353,11 @@
compilationUnits, context);
}
- abstract CompilationUnitTree cuTree();
+ abstract Iterable<? extends CompilationUnitTree> cuTrees();
+
+ CompilationUnitTree firstCuTree() {
+ return cuTrees().iterator().next();
+ }
Diag diag(Diagnostic<? extends JavaFileObject> diag) {
return sourceHandler.diag(diag);
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TreeDissector.java Mon Jan 04 17:07:23 2016 -0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TreeDissector.java Tue Jan 05 10:38:10 2016 -0800
@@ -48,7 +48,10 @@
import java.util.List;
import java.util.Locale;
import java.util.function.BinaryOperator;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
import javax.lang.model.type.TypeMirror;
+import jdk.jshell.Util.Pair;
/**
* Utilities for analyzing compiler API parse trees.
@@ -68,23 +71,48 @@
}
private final TaskFactory.BaseTask bt;
- private ClassTree firstClass;
+ private final ClassTree targetClass;
+ private final CompilationUnitTree targetCompilationUnit;
private SourcePositions theSourcePositions = null;
- TreeDissector(TaskFactory.BaseTask bt) {
+ private TreeDissector(TaskFactory.BaseTask bt, CompilationUnitTree targetCompilationUnit, ClassTree targetClass) {
this.bt = bt;
+ this.targetCompilationUnit = targetCompilationUnit;
+ this.targetClass = targetClass;
+ }
+
+ static TreeDissector createByFirstClass(TaskFactory.BaseTask bt) {
+ Pair<CompilationUnitTree, ClassTree> pair = classes(bt.firstCuTree())
+ .findFirst().orElseGet(() -> new Pair<>(bt.firstCuTree(), null));
+
+ return new TreeDissector(bt, pair.first, pair.second);
}
+ private static final Predicate<? super Tree> isClassOrInterface =
+ t -> t.getKind() == Tree.Kind.CLASS || t.getKind() == Tree.Kind.INTERFACE;
- ClassTree firstClass() {
- if (firstClass == null) {
- firstClass = computeFirstClass();
- }
- return firstClass;
+ private static Stream<Pair<CompilationUnitTree, ClassTree>> classes(CompilationUnitTree cut) {
+ return cut == null
+ ? Stream.empty()
+ : cut.getTypeDecls().stream()
+ .filter(isClassOrInterface)
+ .map(decl -> new Pair<>(cut, (ClassTree)decl));
}
- CompilationUnitTree cuTree() {
- return bt.cuTree();
+ private static Stream<Pair<CompilationUnitTree, ClassTree>> classes(Iterable<? extends CompilationUnitTree> cuts) {
+ return Util.stream(cuts)
+ .flatMap(TreeDissector::classes);
+ }
+
+ static TreeDissector createBySnippet(TaskFactory.BaseTask bt, Snippet si) {
+ String name = si.className();
+
+ Pair<CompilationUnitTree, ClassTree> pair = classes(bt.cuTrees())
+ .filter(p -> p.second.getSimpleName().contentEquals(name))
+ .findFirst().orElseThrow(() ->
+ new IllegalArgumentException("Class " + name + " is not found."));
+
+ return new TreeDissector(bt, pair.first, pair.second);
}
Types types() {
@@ -103,11 +131,11 @@
}
int getStartPosition(Tree tree) {
- return (int) getSourcePositions().getStartPosition(cuTree(), tree);
+ return (int) getSourcePositions().getStartPosition(targetCompilationUnit, tree);
}
int getEndPosition(Tree tree) {
- return (int) getSourcePositions().getEndPosition(cuTree(), tree);
+ return (int) getSourcePositions().getEndPosition(targetCompilationUnit, tree);
}
Range treeToRange(Tree tree) {
@@ -134,9 +162,9 @@
}
Tree firstClassMember() {
- if (firstClass() != null) {
+ if (targetClass != null) {
//TODO: missing classes
- for (Tree mem : firstClass().getMembers()) {
+ for (Tree mem : targetClass.getMembers()) {
if (mem.getKind() == Tree.Kind.VARIABLE) {
return mem;
}
@@ -152,8 +180,8 @@
}
StatementTree firstStatement() {
- if (firstClass() != null) {
- for (Tree mem : firstClass().getMembers()) {
+ if (targetClass != null) {
+ for (Tree mem : targetClass.getMembers()) {
if (mem.getKind() == Tree.Kind.METHOD) {
MethodTree mt = (MethodTree) mem;
if (isDoIt(mt.getName())) {
@@ -169,8 +197,8 @@
}
VariableTree firstVariable() {
- if (firstClass() != null) {
- for (Tree mem : firstClass().getMembers()) {
+ if (targetClass != null) {
+ for (Tree mem : targetClass.getMembers()) {
if (mem.getKind() == Tree.Kind.VARIABLE) {
VariableTree vt = (VariableTree) mem;
return vt;
@@ -180,17 +208,6 @@
return null;
}
- private ClassTree computeFirstClass() {
- if (cuTree() == null) {
- return null;
- }
- for (Tree decl : cuTree().getTypeDecls()) {
- if (decl.getKind() == Tree.Kind.CLASS || decl.getKind() == Tree.Kind.INTERFACE) {
- return (ClassTree) decl;
- }
- }
- return null;
- }
ExpressionInfo typeOfReturnStatement(JavacMessages messages, BinaryOperator<String> fullClassNameAndPackageToClass) {
ExpressionInfo ei = new ExpressionInfo();
@@ -198,7 +215,7 @@
if (unitTree instanceof ReturnTree) {
ei.tree = ((ReturnTree) unitTree).getExpression();
if (ei.tree != null) {
- TreePath viPath = trees().getPath(cuTree(), ei.tree);
+ TreePath viPath = trees().getPath(targetCompilationUnit, ei.tree);
if (viPath != null) {
TypeMirror tm = trees().getTypeMirror(viPath);
if (tm != null) {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Unit.java Mon Jan 04 17:07:23 2016 -0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Unit.java Tue Jan 05 10:38:10 2016 -0800
@@ -225,7 +225,7 @@
return false;
}
- void setStatus() {
+ void setStatus(AnalyzeTask at) {
if (!compilationDiagnostics.hasErrors()) {
status = VALID;
} else if (isRecoverable()) {
@@ -237,7 +237,7 @@
} else {
status = REJECTED;
}
- checkForOverwrite();
+ checkForOverwrite(at);
state.debug(DBG_GEN, "setStatus() %s - status: %s\n",
si, status);
@@ -361,17 +361,18 @@
si, status, unresolved);
}
- private void checkForOverwrite() {
+ private void checkForOverwrite(AnalyzeTask at) {
secondaryEvents = new ArrayList<>();
if (replaceOldEvent != null) secondaryEvents.add(replaceOldEvent);
// Defined methods can overwrite methods of other (equivalent) snippets
if (si.kind() == Kind.METHOD && status.isDefined) {
- String oqpt = ((MethodSnippet) si).qualifiedParameterTypes();
- String nqpt = computeQualifiedParameterTypes(si);
+ MethodSnippet msi = (MethodSnippet)si;
+ String oqpt = msi.qualifiedParameterTypes();
+ String nqpt = computeQualifiedParameterTypes(at, msi);
if (!nqpt.equals(oqpt)) {
- ((MethodSnippet) si).setQualifiedParamaterTypes(nqpt);
- Status overwrittenStatus = overwriteMatchingMethod(si);
+ msi.setQualifiedParamaterTypes(nqpt);
+ Status overwrittenStatus = overwriteMatchingMethod(msi);
if (overwrittenStatus != null) {
prevStatus = overwrittenStatus;
signatureChanged = true;
@@ -383,19 +384,19 @@
// Check if there is a method whose user-declared parameter types are
// different (and thus has a different snippet) but whose compiled parameter
// types are the same. if so, consider it an overwrite replacement.
- private Status overwriteMatchingMethod(Snippet si) {
- String qpt = ((MethodSnippet) si).qualifiedParameterTypes();
+ private Status overwriteMatchingMethod(MethodSnippet msi) {
+ String qpt = msi.qualifiedParameterTypes();
// Look through all methods for a method of the same name, with the
// same computed qualified parameter types
Status overwrittenStatus = null;
for (MethodSnippet sn : state.methods()) {
- if (sn != null && sn != si && sn.status().isActive && sn.name().equals(si.name())) {
+ if (sn != null && sn != msi && sn.status().isActive && sn.name().equals(msi.name())) {
if (qpt.equals(sn.qualifiedParameterTypes())) {
overwrittenStatus = sn.status();
SnippetEvent se = new SnippetEvent(
sn, overwrittenStatus, OVERWRITTEN,
- false, si, null, null);
+ false, msi, null, null);
sn.setOverwritten();
secondaryEvents.add(se);
state.debug(DBG_EVNT,
@@ -408,20 +409,16 @@
return overwrittenStatus;
}
- private String computeQualifiedParameterTypes(Snippet si) {
- MethodSnippet msi = (MethodSnippet) si;
- String qpt;
- AnalyzeTask at = state.taskFactory.new AnalyzeTask(msi.outerWrap());
- String rawSig = new TreeDissector(at).typeOfMethod();
+ private String computeQualifiedParameterTypes(AnalyzeTask at, MethodSnippet msi) {
+ String rawSig = TreeDissector.createBySnippet(at, msi).typeOfMethod();
String signature = expunge(rawSig);
int paren = signature.lastIndexOf(')');
- if (paren < 0) {
- // Uncompilable snippet, punt with user parameter types
- qpt = msi.parameterTypes();
- } else {
- qpt = signature.substring(0, paren + 1);
- }
- return qpt;
+
+ // Extract the parameter type string from the method signature,
+ // if method did not compile use the user-supplied parameter types
+ return paren >= 0
+ ? signature.substring(0, paren + 1)
+ : msi.parameterTypes();
}
SnippetEvent event(String value, Exception exception) {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Util.java Mon Jan 04 17:07:23 2016 -0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Util.java Tue Jan 05 10:38:10 2016 -0800
@@ -91,4 +91,14 @@
static <T> Stream<T> stream(Iterable<T> iterable) {
return StreamSupport.stream(iterable.spliterator(), false);
}
+
+ static class Pair<T, U> {
+ final T first;
+ final U second;
+
+ Pair(T first, U second) {
+ this.first = first;
+ this.second = second;
+ }
+ }
}
--- a/langtools/test/jdk/jshell/ClassesTest.java Mon Jan 04 17:07:23 2016 -0800
+++ b/langtools/test/jdk/jshell/ClassesTest.java Tue Jan 05 10:38:10 2016 -0800
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 8145239
* @summary Tests for EvaluationState.classes
* @build KullaTesting TestingInputStream ExpectedDiagnostic
* @run testng ClassesTest
@@ -174,6 +175,27 @@
assertActiveKeys();
}
+ public void classesRedeclaration3() {
+ Snippet a = classKey(assertEval("class A { }"));
+ assertClasses(clazz(KullaTesting.ClassType.CLASS, "A"));
+ assertActiveKeys();
+
+ Snippet test1 = methodKey(assertEval("A test() { return null; }"));
+ Snippet test2 = methodKey(assertEval("void test(A a) { }"));
+ Snippet test3 = methodKey(assertEval("void test(int n) {A a;}"));
+ assertActiveKeys();
+
+ assertEval("interface A { }",
+ ste(MAIN_SNIPPET, VALID, VALID, true, null),
+ ste(test1, VALID, VALID, true, MAIN_SNIPPET),
+ ste(test2, VALID, VALID, true, MAIN_SNIPPET),
+ ste(test3, VALID, VALID, false, MAIN_SNIPPET),
+ ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+ assertClasses(clazz(KullaTesting.ClassType.INTERFACE, "A"));
+ assertMethods(method("()A", "test"), method("(A)void", "test"), method("(int)void", "test"));
+ assertActiveKeys();
+ }
+
public void classesCyclic1() {
Snippet b = classKey(assertEval("class B extends A { }",
added(RECOVERABLE_NOT_DEFINED)));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/DiagnosticRewriterTest.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8145466
+ * @summary javac: No line numbers in compilation error
+ * @compile/fail/ref=DiagnosticRewriterTest.out -Xdiags:compact -XDrawDiagnostics DiagnosticRewriterTest.java
+ */
+
+class DiagnosticRewriterTest {
+ void test() {
+ new Object() {
+ void g() {
+ m(2L);
+ }
+ };
+ }
+
+ void m(int i) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/DiagnosticRewriterTest.out Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,3 @@
+DiagnosticRewriterTest.java:12:15: compiler.err.prob.found.req: (compiler.misc.possible.loss.of.precision: long, int)
+- compiler.note.compressed.diags
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/DiagnosticRewriterTest2.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,22 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8145466
+ * @summary javac: No line numbers in compilation error
+ * @compile/fail/ref=DiagnosticRewriterTest2.out -Xdiags:compact -XDrawDiagnostics DiagnosticRewriterTest2.java
+ */
+
+class DiagnosticRewriterTest2 {
+ class Bar {
+ Bar(Object o) { }
+ }
+ void test() {
+ new Bar(null) {
+ void g() {
+ m(2L);
+ m();
+ }
+ };
+ }
+
+ void m(int i) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/DiagnosticRewriterTest2.out Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,4 @@
+DiagnosticRewriterTest2.java:15:15: compiler.err.prob.found.req: (compiler.misc.possible.loss.of.precision: long, int)
+DiagnosticRewriterTest2.java:16:13: compiler.err.cant.apply.symbol: kindname.method, m, int, compiler.misc.no.args, kindname.class, DiagnosticRewriterTest2, (compiler.misc.arg.length.mismatch)
+- compiler.note.compressed.diags
+2 errors
--- a/langtools/test/tools/javac/proprietary/WarnVariable.java Mon Jan 04 17:07:23 2016 -0800
+++ b/langtools/test/tools/javac/proprietary/WarnVariable.java Tue Jan 05 10:38:10 2016 -0800
@@ -3,7 +3,7 @@
* @bug 6380059
* @summary Emit warnings for proprietary packages in the boot class path
* @author Peter von der Ah\u00e9
- * @modules java.base/sun.misc
+ * @modules java.base/sun.security.x509
* @compile WarnVariable.java
* @compile/fail/ref=WarnVariable.out -XDrawDiagnostics -Werror WarnVariable.java
* @compile/fail/ref=WarnVariable.out -XDrawDiagnostics -Werror -nowarn WarnVariable.java
@@ -12,6 +12,6 @@
public class WarnVariable {
public static void main(String... args) {
- System.out.println(sun.misc.FloatConsts.POSITIVE_INFINITY);
+ System.out.println(sun.security.x509.X509CertImpl.NAME);
}
}
--- a/langtools/test/tools/javac/proprietary/WarnVariable.out Mon Jan 04 17:07:23 2016 -0800
+++ b/langtools/test/tools/javac/proprietary/WarnVariable.out Tue Jan 05 10:38:10 2016 -0800
@@ -1,4 +1,4 @@
-WarnVariable.java:15:36: compiler.warn.sun.proprietary: sun.misc.FloatConsts
+WarnVariable.java:15:45: compiler.warn.sun.proprietary: sun.security.x509.X509CertImpl
- compiler.err.warnings.and.werror
1 error
1 warning
--- a/langtools/test/tools/javac/proprietary/WarnWildcard.java Mon Jan 04 17:07:23 2016 -0800
+++ b/langtools/test/tools/javac/proprietary/WarnWildcard.java Tue Jan 05 10:38:10 2016 -0800
@@ -3,7 +3,7 @@
* @bug 6380059
* @summary Emit warnings for proprietary packages in the boot class path
* @author Peter von der Ah\u00e9
- * @modules java.base/sun.misc
+ * @modules java.base/sun.security.x509
* @compile WarnWildcard.java
* @compile/fail/ref=WarnWildcard.out -XDrawDiagnostics -Werror WarnWildcard.java
* @compile/fail/ref=WarnWildcard.out -XDrawDiagnostics -Werror -nowarn WarnWildcard.java
@@ -11,5 +11,5 @@
*/
public class WarnWildcard {
- java.util.Collection<? extends sun.misc.FloatConsts> x;
+ java.util.Collection<? extends sun.security.x509.X509CertImpl> x;
}
--- a/langtools/test/tools/javac/proprietary/WarnWildcard.out Mon Jan 04 17:07:23 2016 -0800
+++ b/langtools/test/tools/javac/proprietary/WarnWildcard.out Tue Jan 05 10:38:10 2016 -0800
@@ -1,4 +1,4 @@
-WarnWildcard.java:14:44: compiler.warn.sun.proprietary: sun.misc.FloatConsts
+WarnWildcard.java:14:53: compiler.warn.sun.proprietary: sun.security.x509.X509CertImpl
- compiler.err.warnings.and.werror
1 error
1 warning
--- a/modules.xml Mon Jan 04 17:07:23 2016 -0800
+++ b/modules.xml Tue Jan 05 10:38:10 2016 -0800
@@ -223,6 +223,10 @@
<to>jdk.dev</to>
</export>
<export>
+ <name>jdk.internal.math</name>
+ <to>java.desktop</to>
+ </export>
+ <export>
<name>jdk.internal.misc</name>
<to>java.corba</to>
<to>java.desktop</to>
@@ -295,6 +299,7 @@
<to>jdk.security.jgss</to>
<to>jdk.snmp</to>
<to>jdk.vm.ci</to>
+ <to>jdk.zipfs</to>
<to>java.instrument</to>
</export>
<export>
--- a/nashorn/.hgtags Mon Jan 04 17:07:23 2016 -0800
+++ b/nashorn/.hgtags Tue Jan 05 10:38:10 2016 -0800
@@ -332,3 +332,4 @@
d52c09d5d98a81ee6102a25f662ec4b9ae614163 jdk-9+96
2beaef2b6a880c0bff8c9f57ffca33477d647f8b jdk-9+97
68a36216f70c0de4c7e36f8978995934fc72ec03 jdk-9+98
+74ddd1339c57cf2c2a13e34e1760006c2e54d1fc jdk-9+99
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java Mon Jan 04 17:07:23 2016 -0800
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java Tue Jan 05 10:38:10 2016 -0800
@@ -59,8 +59,8 @@
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_CREATEBUILTIN_SPECS_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETDOCUMENTATION;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETDOCUMENTATION_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETDOCUMENTATIONKEY;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETDOCUMENTATIONKEY_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_TYPE;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SETTER_PREFIX;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.TYPE_OBJECT;
@@ -274,7 +274,7 @@
addField(cv, name, OBJECT_DESC);
}
- static void newFunction(final MethodGenerator mi, final String className, final MemberInfo memInfo, final List<MemberInfo> specs) {
+ static void newFunction(final MethodGenerator mi, final String objName, final String className, final MemberInfo memInfo, final List<MemberInfo> specs) {
final boolean arityFound = (memInfo.getArity() != MemberInfo.DEFAULT_ARITY);
mi.loadLiteral(memInfo.getName());
@@ -294,12 +294,9 @@
mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETARITY, SCRIPTFUNCTION_SETARITY_DESC);
}
- String doc = memInfo.getDocumentation();
- if (doc != null) {
- mi.dup();
- mi.loadLiteral(memInfo.getDocumentation());
- mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETDOCUMENTATION, SCRIPTFUNCTION_SETDOCUMENTATION_DESC);
- }
+ mi.dup();
+ mi.loadLiteral(memInfo.getDocumentationKey(objName));
+ mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETDOCUMENTATIONKEY, SCRIPTFUNCTION_SETDOCUMENTATIONKEY_DESC);
}
static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo memInfo) {
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java Mon Jan 04 17:07:23 2016 -0800
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java Tue Jan 05 10:38:10 2016 -0800
@@ -42,8 +42,8 @@
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_INIT_DESC4;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETDOCUMENTATION;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETDOCUMENTATION_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETDOCUMENTATIONKEY;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETDOCUMENTATIONKEY_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETPROTOTYPE;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETPROTOTYPE_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_TYPE;
@@ -161,13 +161,11 @@
mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETARITY,
SCRIPTFUNCTION_SETARITY_DESC);
}
- final String doc = constructor.getDocumentation();
- if (doc != null) {
- mi.loadThis();
- mi.loadLiteral(doc);
- mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETDOCUMENTATION,
- SCRIPTFUNCTION_SETDOCUMENTATION_DESC);
- }
+
+ mi.loadThis();
+ mi.loadLiteral(scriptClassInfo.getName());
+ mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETDOCUMENTATIONKEY,
+ SCRIPTFUNCTION_SETDOCUMENTATIONKEY_DESC);
}
mi.returnVoid();
mi.computeMaxs();
@@ -208,7 +206,7 @@
continue;
}
mi.loadThis();
- newFunction(mi, scriptClassInfo.getJavaName(), memInfo, scriptClassInfo.findSpecializations(memInfo.getJavaName()));
+ newFunction(mi, scriptClassInfo.getName(), scriptClassInfo.getJavaName(), memInfo, scriptClassInfo.findSpecializations(memInfo.getJavaName()));
mi.putField(className, memInfo.getJavaName(), OBJECT_DESC);
}
}
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java Mon Jan 04 17:07:23 2016 -0800
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java Tue Jan 05 10:38:10 2016 -0800
@@ -85,8 +85,6 @@
private MemberInfo.Kind kind;
// script property name
private String name;
- // documentation for this member
- private String documentation;
// script property attributes
private int attributes;
// name of the java member
@@ -139,20 +137,6 @@
}
/**
- * @return the documentation
- */
- public String getDocumentation() {
- return documentation;
- }
-
- /**
- * @param doc the documentation to set
- */
- public void setDocumentation(final String doc) {
- this.documentation = doc;
- }
-
- /**
* Tag something as specialized constructor or not
* @param isSpecializedConstructor boolean, true if specialized constructor
*/
@@ -560,4 +544,25 @@
void setArity(final int arity) {
this.arity = arity;
}
+
+ String getDocumentationKey(final String objName) {
+ if (kind == Kind.FUNCTION) {
+ StringBuilder buf = new StringBuilder(objName);
+ switch (where) {
+ case CONSTRUCTOR:
+ break;
+ case PROTOTYPE:
+ buf.append(".prototype");
+ break;
+ case INSTANCE:
+ buf.append(".this");
+ break;
+ }
+ buf.append('.');
+ buf.append(name);
+ return buf.toString();
+ }
+
+ return null;
+ }
}
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java Mon Jan 04 17:07:23 2016 -0800
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java Tue Jan 05 10:38:10 2016 -0800
@@ -142,7 +142,7 @@
continue;
}
mi.loadThis();
- newFunction(mi, scriptClassInfo.getJavaName(), memInfo, scriptClassInfo.findSpecializations(memInfo.getJavaName()));
+ newFunction(mi, scriptClassInfo.getName(), scriptClassInfo.getJavaName(), memInfo, scriptClassInfo.findSpecializations(memInfo.getJavaName()));
mi.putField(className, memInfo.getJavaName(), OBJECT_DESC);
}
}
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java Mon Jan 04 17:07:23 2016 -0800
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java Tue Jan 05 10:38:10 2016 -0800
@@ -206,7 +206,6 @@
// These could be "null" if values are not supplied,
// in which case we have to use the default values.
private String name;
- private String documentation;
private Integer attributes;
private Integer arity;
private Where where;
@@ -223,13 +222,6 @@
name = null;
}
break;
- case "documentation":
- this.documentation = (String)annotationValue;
- if (documentation.isEmpty()) {
- documentation = null;
- }
-
- break;
case "attributes":
this.attributes = (Integer)annotationValue;
break;
@@ -279,7 +271,6 @@
memInfo.setName(name == null ? methodName : name);
}
- memInfo.setDocumentation(documentation);
memInfo.setAttributes(attributes == null ? MemberInfo.DEFAULT_ATTRIBUTES : attributes);
memInfo.setArity((arity == null)? MemberInfo.DEFAULT_ARITY : arity);
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java Mon Jan 04 17:07:23 2016 -0800
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java Tue Jan 05 10:38:10 2016 -0800
@@ -170,7 +170,7 @@
if (memInfo.isInstanceFunction()) {
super.visitVarInsn(ALOAD, 0);
- ClassGenerator.newFunction(delegateMV, scriptClassInfo.getJavaName(), memInfo, scriptClassInfo.findSpecializations(memInfo.getJavaName()));
+ ClassGenerator.newFunction(delegateMV, scriptClassInfo.getName(), scriptClassInfo.getJavaName(), memInfo, scriptClassInfo.findSpecializations(memInfo.getJavaName()));
super.visitFieldInsn(PUTFIELD, scriptClassInfo.getJavaName(),
memInfo.getJavaName(), OBJECT_DESC);
}
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java Mon Jan 04 17:07:23 2016 -0800
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java Tue Jan 05 10:38:10 2016 -0800
@@ -118,8 +118,8 @@
static final String SCRIPTFUNCTION_TYPE = TYPE_SCRIPTFUNCTION.getInternalName();
static final String SCRIPTFUNCTION_SETARITY = "setArity";
static final String SCRIPTFUNCTION_SETARITY_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE);
- static final String SCRIPTFUNCTION_SETDOCUMENTATION = "setDocumentation";
- static final String SCRIPTFUNCTION_SETDOCUMENTATION_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING);
+ static final String SCRIPTFUNCTION_SETDOCUMENTATIONKEY = "setDocumentationKey";
+ static final String SCRIPTFUNCTION_SETDOCUMENTATIONKEY_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING);
static final String SCRIPTFUNCTION_SETPROTOTYPE = "setPrototype";
static final String SCRIPTFUNCTION_SETPROTOTYPE_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT);
static final String SCRIPTFUNCTION_CREATEBUILTIN = "createBuiltin";
--- a/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/beans/AbstractJavaLinker.java Mon Jan 04 17:07:23 2016 -0800
+++ b/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/beans/AbstractJavaLinker.java Tue Jan 05 10:38:10 2016 -0800
@@ -790,7 +790,7 @@
*/
@SuppressWarnings("unused")
private Object getPropertyGetterHandle(final Object id) {
- return propertyGetters.get(id);
+ return propertyGetters.get(String.valueOf(id));
}
// Type is MethodHandle(BeanLinker, MethodType, LinkerServices, Object, String, Object), of which the two "Object"
--- a/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java Mon Jan 04 17:07:23 2016 -0800
+++ b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java Tue Jan 05 10:38:10 2016 -0800
@@ -47,10 +47,10 @@
import jdk.nashorn.internal.objects.NativeJava;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.NativeJavaPackage;
-import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.Property;
import jdk.nashorn.internal.runtime.ScriptEnvironment;
import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.tools.Shell;
@@ -60,6 +60,8 @@
public final class Main extends Shell {
private Main() {}
+ private static final String DOC_PROPERTY_NAME = "__doc__";
+
static final boolean DEBUG = Boolean.getBoolean("nashorn.jjs.debug");
static final boolean HEADLESS = GraphicsEnvironment.isHeadless();
@@ -132,12 +134,17 @@
final String pkgName = ((NativeJavaPackage)res).getName();
final String url = pkgName.replace('.', '/') + "/package-summary.html";
openBrowserForJavadoc(url);
- } else if (res instanceof ScriptFunction) {
- return ((ScriptFunction)res).getDocumentation();
+ } else if (res instanceof ScriptObject) {
+ final ScriptObject sobj = (ScriptObject)res;
+ if (sobj.has(DOC_PROPERTY_NAME)) {
+ return toString(sobj.get(DOC_PROPERTY_NAME), global);
+ } else if (sobj instanceof ScriptFunction) {
+ return ((ScriptFunction)sobj).getDocumentation();
+ }
}
// FIXME: better than toString for other cases?
- return JSType.toString(res);
+ return toString(res, global);
}
} catch (Exception ignored) {
}
@@ -253,7 +260,7 @@
try {
final Object res = context.eval(global, source, global, "<shell>");
if (res != UNDEFINED) {
- err.println(JSType.toString(res));
+ err.println(toString(res, global));
}
} catch (final Exception e) {
err.println(e);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeObject.java Mon Jan 04 17:07:23 2016 -0800
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeObject.java Tue Jan 05 10:38:10 2016 -0800
@@ -148,8 +148,7 @@
* @param buf external buffer - should be a nio ByteBuffer
* @return the 'obj' object
*/
- @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
- documentation = "sets ByteBuffer to hold indexed data (nashorn extension)")
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static ScriptObject setIndexedPropertiesToExternalArrayData(final Object self, final Object obj, final Object buf) {
Global.checkObject(obj);
final ScriptObject sobj = (ScriptObject)obj;
@@ -169,8 +168,7 @@
* @param obj object to get prototype from
* @return the prototype of an object
*/
- @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
- documentation = "returns the prototype of the specified object")
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object getPrototypeOf(final Object self, final Object obj) {
if (obj instanceof ScriptObject) {
return ((ScriptObject)obj).getProto();
@@ -197,8 +195,7 @@
* @param proto prototype object to be used
* @return object whose prototype is set
*/
- @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
- documentation = "sets the prototype of the given object (ES6)")
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object setPrototypeOf(final Object self, final Object obj, final Object proto) {
if (obj instanceof ScriptObject) {
((ScriptObject)obj).setPrototypeOf(proto);
@@ -219,8 +216,7 @@
* @param prop property descriptor
* @return property descriptor
*/
- @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
- documentation = "returns a property descriptor for an own property (not inherited property)")
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object getOwnPropertyDescriptor(final Object self, final Object obj, final Object prop) {
if (obj instanceof ScriptObject) {
final String key = JSType.toString(prop);
@@ -244,8 +240,7 @@
* @param obj object to query for property names
* @return array of property names
*/
- @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
- documentation = "returns an array of all properties (enumerable or not) found directly on the given object")
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static ScriptObject getOwnPropertyNames(final Object self, final Object obj) {
if (obj instanceof ScriptObject) {
return new NativeArray(((ScriptObject)obj).getOwnKeys(true));
@@ -263,8 +258,7 @@
* @param obj object to query for property names
* @return array of property names
*/
- @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
- documentation = "returns an array of all symbol properties found directly on the given object (ES6)")
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static ScriptObject getOwnPropertySymbols(final Object self, final Object obj) {
if (obj instanceof ScriptObject) {
return new NativeArray(((ScriptObject)obj).getOwnSymbols(true));
@@ -282,8 +276,7 @@
* @param props properties to define
* @return object created
*/
- @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
- documentation = "creates a new object with the specified prototype object and properties")
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static ScriptObject create(final Object self, final Object proto, final Object props) {
if (proto != null) {
Global.checkObject(proto);
@@ -309,8 +302,7 @@
* @param attr attributes for property descriptor
* @return object
*/
- @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
- documentation = "adds an own property and/or update the attributes of an existing own property of an object")
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static ScriptObject defineProperty(final Object self, final Object obj, final Object prop, final Object attr) {
final ScriptObject sobj = Global.checkObject(obj);
sobj.defineOwnProperty(JSType.toPropertyKey(prop), attr, true);
@@ -325,8 +317,7 @@
* @param props properties
* @return object
*/
- @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
- documentation = "defines new or modifies existing properties directly on the given object")
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static ScriptObject defineProperties(final Object self, final Object obj, final Object props) {
final ScriptObject sobj = Global.checkObject(obj);
final Object propsObj = Global.toObject(props);
@@ -348,8 +339,7 @@
* @param obj object to seal
* @return sealed object
*/
- @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
- documentation = "prevents new properties from being added to the given object and marks existing properties as non-configurable")
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object seal(final Object self, final Object obj) {
if (obj instanceof ScriptObject) {
return ((ScriptObject)obj).seal();
@@ -368,8 +358,7 @@
* @param obj object to freeze
* @return frozen object
*/
- @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
- documentation = "prevents new properties from being added to the given object and prevents existing properties from being removed or re-configured")
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object freeze(final Object self, final Object obj) {
if (obj instanceof ScriptObject) {
return ((ScriptObject)obj).freeze();
@@ -387,8 +376,7 @@
* @param obj object, for which to set the internal extensible property to false
* @return object
*/
- @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
- documentation = "prevents new properties from ever being added to the given object")
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object preventExtensions(final Object self, final Object obj) {
if (obj instanceof ScriptObject) {
return ((ScriptObject)obj).preventExtensions();
@@ -406,8 +394,7 @@
* @param obj check whether an object is sealed
* @return true if sealed, false otherwise
*/
- @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
- documentation = "tells if an object is sealed or not")
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static boolean isSealed(final Object self, final Object obj) {
if (obj instanceof ScriptObject) {
return ((ScriptObject)obj).isSealed();
@@ -425,8 +412,7 @@
* @param obj check whether an object
* @return true if object is frozen, false otherwise
*/
- @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
- documentation = "tells if an object is fronzen or not")
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static boolean isFrozen(final Object self, final Object obj) {
if (obj instanceof ScriptObject) {
return ((ScriptObject)obj).isFrozen();
@@ -444,8 +430,7 @@
* @param obj check whether an object is extensible
* @return true if object is extensible, false otherwise
*/
- @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
- documentation = "tells if an object is extensible or not")
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static boolean isExtensible(final Object self, final Object obj) {
if (obj instanceof ScriptObject) {
return ((ScriptObject)obj).isExtensible();
@@ -463,8 +448,7 @@
* @param obj object from which to extract keys
* @return array of keys in object
*/
- @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
- documentation = "returns an array of the given object's own enumerable properties")
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static ScriptObject keys(final Object self, final Object obj) {
if (obj instanceof ScriptObject) {
final ScriptObject sobj = (ScriptObject)obj;
@@ -487,7 +471,7 @@
* @param value value of object to be instantiated
* @return the new NativeObject
*/
- @Constructor(documentation = "creates a new script object or converts given value as a script object")
+ @Constructor
public static Object construct(final boolean newObj, final Object self, final Object value) {
final JSType type = JSType.ofNoFunction(value);
@@ -521,8 +505,7 @@
* @param self self reference
* @return ToString of object
*/
- @Function(attributes = Attribute.NOT_ENUMERABLE,
- documentation = "returns a string representing of this object")
+ @Function(attributes = Attribute.NOT_ENUMERABLE)
public static String toString(final Object self) {
return ScriptRuntime.builtinObjectToString(self);
}
@@ -575,8 +558,7 @@
* @param v property to check for
* @return true if property exists in object
*/
- @Function(attributes = Attribute.NOT_ENUMERABLE,
- documentation = "tells whether this object has the specified property or not")
+ @Function(attributes = Attribute.NOT_ENUMERABLE)
public static boolean hasOwnProperty(final Object self, final Object v) {
// Convert ScriptObjects to primitive with String.class hint
// but no need to convert other primitives to string.
@@ -593,8 +575,7 @@
* @param v v prototype object to check against
* @return true if object is prototype of v
*/
- @Function(attributes = Attribute.NOT_ENUMERABLE,
- documentation = "tests for this object in another object's prototype chain")
+ @Function(attributes = Attribute.NOT_ENUMERABLE)
public static boolean isPrototypeOf(final Object self, final Object v) {
if (!(v instanceof ScriptObject)) {
return false;
@@ -620,8 +601,7 @@
* @param v property to check if enumerable
* @return true if property is enumerable
*/
- @Function(attributes = Attribute.NOT_ENUMERABLE,
- documentation = "tells whether the given property is enumerable or not")
+ @Function(attributes = Attribute.NOT_ENUMERABLE)
public static boolean propertyIsEnumerable(final Object self, final Object v) {
final String str = JSType.toString(v);
final Object obj = Global.toObject(self);
@@ -696,8 +676,7 @@
* @param source the source object whose properties are bound to the target
* @return the target object after property binding
*/
- @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
- documentation = "binds the source object's properties to the target object (nashorn extension)")
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object bindProperties(final Object self, final Object target, final Object source) {
// target object has to be a ScriptObject
final ScriptObject targetObj = Global.checkObject(target);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/annotations/Constructor.java Mon Jan 04 17:07:23 2016 -0800
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/annotations/Constructor.java Tue Jan 05 10:38:10 2016 -0800
@@ -48,9 +48,4 @@
* arity.
*/
public int arity() default -2;
-
- /**
- * @return the documentation string for this constructor.
- */
- public String documentation() default "";
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/annotations/Function.java Mon Jan 04 17:07:23 2016 -0800
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/annotations/Function.java Tue Jan 05 10:38:10 2016 -0800
@@ -60,9 +60,4 @@
* @return where this function lives.
*/
public Where where() default Where.PROTOTYPE;
-
- /**
- * @return return the documentation string for this function.
- */
- public String documentation() default "";
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java Mon Jan 04 17:07:23 2016 -0800
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java Tue Jan 05 10:38:10 2016 -0800
@@ -36,6 +36,9 @@
*/
final class FinalScriptFunctionData extends ScriptFunctionData {
+ // documentation key for this function, may be null
+ private String docKey;
+
private static final long serialVersionUID = -930632846167768864L;
/**
@@ -73,6 +76,23 @@
}
@Override
+ String getDocumentationKey() {
+ return docKey;
+ }
+
+ @Override
+ void setDocumentationKey(final String docKey) {
+ this.docKey = docKey;
+ }
+
+ @Override
+ String getDocumentation() {
+ String doc = docKey != null?
+ FunctionDocumentation.getDoc(docKey) : null;
+ return doc != null? doc : super.getDocumentation();
+ }
+
+ @Override
protected boolean needsCallee() {
final boolean needsCallee = code.getFirst().needsCallee();
assert allNeedCallee(needsCallee);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/FunctionDocumentation.java Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.internal.runtime;
+
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+/**
+ * Utility class to fetch documentation for built-in functions, constructors.
+ */
+final class FunctionDocumentation {
+ private FunctionDocumentation() {}
+
+ private static final String DOCS_RESOURCE = "jdk.nashorn.internal.runtime.resources.Functions";
+
+ private static final ResourceBundle FUNC_DOCS;
+ static {
+ FUNC_DOCS = ResourceBundle.getBundle(DOCS_RESOURCE, Locale.getDefault());
+ }
+
+ static String getDoc(final String docKey) {
+ try {
+ return FUNC_DOCS.getString(docKey);
+ } catch (final RuntimeException ignored) {
+ return null;
+ }
+ }
+}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunction.java Mon Jan 04 17:07:23 2016 -0800
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunction.java Tue Jan 05 10:38:10 2016 -0800
@@ -655,12 +655,21 @@
}
/**
- * Set the documentation for this function
+ * Get the documentation key for this function
*
- * @param doc documentation String for this function
+ * @return the documentation key
*/
- public final void setDocumentation(final String doc) {
- data.setDocumentation(doc);
+ public final String getDocumentationKey() {
+ return data.getDocumentationKey();
+ }
+
+ /**
+ * Set the documentation key for this function
+ *
+ * @param docKey documentation key String for this function
+ */
+ public final void setDocumentationKey(final String docKey) {
+ data.setDocumentationKey(docKey);
}
/**
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunctionData.java Mon Jan 04 17:07:23 2016 -0800
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunctionData.java Tue Jan 05 10:38:10 2016 -0800
@@ -70,9 +70,6 @@
// value, the function might still be capable of receiving variable number of arguments, see isVariableArity.
private int arity;
- // this may be null, if not available
- private String documentation;
-
/**
* A pair of method handles used for generic invoker and constructor. Field is volatile as it can be initialized by
* multiple threads concurrently, but we still tolerate a race condition in it as all values stored into it are
@@ -121,8 +118,12 @@
return arity;
}
- final String getDocumentation() {
- return documentation != null? documentation : toSource();
+ String getDocumentation() {
+ return toSource();
+ }
+
+ String getDocumentationKey() {
+ return null;
}
final boolean isVariableArity() {
@@ -149,10 +150,10 @@
*
* @param doc documentation for this function
*/
- void setDocumentation(final String doc) {
- this.documentation = doc;
+ void setDocumentationKey(final String docKey) {
}
+
CompiledFunction bind(final CompiledFunction originalInv, final ScriptFunction fn, final Object self, final Object[] args) {
final MethodHandle boundInvoker = bindInvokeHandle(originalInv.createComposableInvoker(), fn, self, args);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Functions.properties Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,44 @@
+Object.setIndexedPropertiesToExternalArrayData=sets ByteBuffer to hold indexed data (nashorn extension)
+
+Object.getPrototypeOf=returns the prototype of the specified object
+
+Object.setPrototypeOf=sets the prototype of the given object (ES6)
+
+Object.getOwnPropertyDescriptor=returns a property descriptor for an own property (not inherited property)
+
+Object.getOwnPropertyNames=returns an array of all properties (enumerable or not) found directly on the given object
+
+Object.getOwnPropertySymbols=returns an array of all symbol properties found directly on the given object (ES6)
+
+Object.create=creates a new object with the specified prototype object and properties
+
+Object.defineProperty=adds an own property and/or update the attributes of an existing own property of an object
+
+Object.defineProperties=defines new or modifies existing properties directly on the given object
+
+Object.seal=prevents new properties from being added to the given object and marks existing properties as non-configurable
+
+Object.freeze=prevents new properties from being added to the given object and prevents existing properties from being removed or re-configured
+
+Object.preventExtensions=prevents new properties from ever being added to the given object
+
+Object.isSealed=tells if an object is sealed or not
+
+Object.isFrozen=tells if an object is fronzen or not
+
+Object.isExtensible=tells if an object is extensible or not
+
+Object.keys=returns an array of the given object's own enumerable properties
+
+Object=creates a new script object or converts given value as a script object
+
+Object.prototype.toString=returns a string representing of this object
+
+Object.prototype.hasOwnProperty=tells whether this object has the specified property or not
+
+Object.prototype.isPrototypeOf=tests for this object in another object's prototype chain
+
+Object.prototype.propertyIsEnumerable=tells whether the given property is enumerable or not
+
+Object.bindProperties=binds the source object's properties to the target object (nashorn extension)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8146147.js Tue Jan 05 10:38:10 2016 -0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8146147: Java linker indexed property getter does not work for computed nashorn string
+ *
+ * @test
+ * @run
+ */
+
+var locale = java.util.Locale.ENGLISH;
+var prop = 'ISO3Language';
+var prop1 = 'ISO3';
+var prop2 = prop1 + 'Language';
+var prop3 = String(prop2);
+
+function checkLang(obj) {
+ if (obj != "eng") {
+ throw new Error("FAILED: expected 'eng', got " + obj);
+ }
+}
+
+checkLang(locale.ISO3Language);
+checkLang(locale['ISO3Language']);
+checkLang(locale[prop]);
+checkLang(locale[prop1 + 'Language']);
+checkLang(locale[prop2]);
+checkLang(locale[prop3]);
+checkLang(locale[String(prop1 + 'Language')]);