From 9f4631e7722a09451b75b85e40fbf0b5adc59c82 Mon Sep 17 00:00:00 2001 From: Jaroslav Bachorik Date: Mon, 16 Feb 2015 10:53:49 +0100 Subject: [PATCH 01/29] 8072908: com/sun/management/OperatingSystemMXBean/TestTotalSwap.sh fails on OS X with exit code 2 Reviewed-by: dholmes, sla --- ...lSwapSpaceSize.java => TestTotalSwap.java} | 97 +++++++++++++----- .../OperatingSystemMXBean/TestTotalSwap.sh | 99 ------------------- 2 files changed, 75 insertions(+), 121 deletions(-) rename jdk/test/com/sun/management/OperatingSystemMXBean/{GetTotalSwapSpaceSize.java => TestTotalSwap.java} (52%) delete mode 100644 jdk/test/com/sun/management/OperatingSystemMXBean/TestTotalSwap.sh diff --git a/jdk/test/com/sun/management/OperatingSystemMXBean/GetTotalSwapSpaceSize.java b/jdk/test/com/sun/management/OperatingSystemMXBean/TestTotalSwap.java similarity index 52% rename from jdk/test/com/sun/management/OperatingSystemMXBean/GetTotalSwapSpaceSize.java rename to jdk/test/com/sun/management/OperatingSystemMXBean/TestTotalSwap.java index 26d49cc67ee..b21eb29b804 100644 --- a/jdk/test/com/sun/management/OperatingSystemMXBean/GetTotalSwapSpaceSize.java +++ b/jdk/test/com/sun/management/OperatingSystemMXBean/TestTotalSwap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -22,11 +22,16 @@ */ /* - * - * + * @test * @bug 4858522 * @summary Basic unit test of OperatingSystemMXBean.getTotalSwapSpaceSize() + * + * @library /lib/testlibrary + * @build TestTotalSwap jdk.testlibrary.* + * @run main TestTotalSwap + * * @author Steve Bohne + * @author Jaroslav Bachorik */ /* @@ -50,9 +55,13 @@ import com.sun.management.OperatingSystemMXBean; import java.lang.management.*; -public class GetTotalSwapSpaceSize { +import jdk.testlibrary.OSInfo; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.OutputAnalyzer; - private static OperatingSystemMXBean mbean = +public class TestTotalSwap { + + private static final OperatingSystemMXBean mbean = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean(); @@ -62,19 +71,9 @@ public class GetTotalSwapSpaceSize { private static long min_size_for_pass = 0; private static final long MAX_SIZE_FOR_PASS = Long.MAX_VALUE; - private static boolean trace = false; - - public static void main(String args[]) throws Exception { - if (args.length > 1 && args[1].equals("trace")) { - trace = true; - } - - long expected_swap_size = 0; - - if (args.length < 1 || args.length > 2) { - throw new IllegalArgumentException("Unexpected number of args " + args.length); - } + public static void main(String args[]) throws Throwable { + long expected_swap_size = getSwapSizeFromOs(); long min_size = mbean.getFreeSwapSpaceSize(); if (min_size > 0) { @@ -83,12 +82,9 @@ public class GetTotalSwapSpaceSize { long size = mbean.getTotalSwapSpaceSize(); - if (trace) { - System.out.println("Total swap space size in bytes: " + size); - } + System.out.println("Total swap space size in bytes: " + size); - if (!args[0].matches("sanity-only")) { - expected_swap_size = Long.parseLong(args[0]); + if (expected_swap_size > -1) { if (size != expected_swap_size) { throw new RuntimeException("Expected total swap size : " + expected_swap_size + @@ -97,6 +93,7 @@ public class GetTotalSwapSpaceSize { } } + // sanity check if (size < min_size_for_pass || size > MAX_SIZE_FOR_PASS) { throw new RuntimeException("Total swap space size " + "illegal value: " + size + " bytes " + @@ -106,4 +103,60 @@ public class GetTotalSwapSpaceSize { System.out.println("Test passed."); } + + private static long getSwapSizeFromOs() throws Throwable { + OSInfo.OSType os = OSInfo.getOSType(); + + switch (os) { + // total used free shared buffers cached + // Mem: 16533540864 13638467584 2895073280 534040576 1630248960 6236909568 + // -/+ buffers/cache: 5771309056 10762231808 + // Swap: 15999168512 0 15999168512 + + case LINUX: { + String swapSizeStr = ProcessTools.executeCommand("free", "-b") + .firstMatch("Swap:\\s+([0-9]+)\\s+.*", 1); + return Long.parseLong(swapSizeStr); + } + case SOLARIS: { + // swapfile dev swaplo blocks free + // /dev/dsk/c0t0d0s1 136,1 16 1638608 1600528 + OutputAnalyzer out= ProcessTools.executeCommand( + "/usr/sbin/swap", + "-l" + ); + + long swapSize = 0; + + for (String line : out.asLines()) { + if (line.contains("swapfile")) continue; + + String[] vals = line.split("\\s+"); + if (vals.length == 5) { + swapSize += Long.parseLong(vals[3]) * 512; // size is reported in 512b blocks + } + } + + return swapSize; + } + case MACOSX: { + // total = 8192.00M used = 7471.11M free = 720.89M (encrypted) + String swapSizeStr = ProcessTools.executeCommand( + "/usr/sbin/sysctl", + "-n", + "vm.swapusage" + ).firstMatch("total\\s+=\\s+([0-9]+(\\.[0-9]+)?[Mm]?).*", 1); + if (swapSizeStr.toLowerCase().endsWith("m")) { + swapSizeStr = swapSizeStr.substring(0, swapSizeStr.length() - 1); + return (long)(Double.parseDouble(swapSizeStr) * 1024 * 1024); // size in MB + } + return (long)(Double.parseDouble(swapSizeStr) * 1024 * 1024); + } + default: { + System.err.println("Unsupported operating system: " + os); + } + } + + return -1; + } } diff --git a/jdk/test/com/sun/management/OperatingSystemMXBean/TestTotalSwap.sh b/jdk/test/com/sun/management/OperatingSystemMXBean/TestTotalSwap.sh deleted file mode 100644 index a4f3726a643..00000000000 --- a/jdk/test/com/sun/management/OperatingSystemMXBean/TestTotalSwap.sh +++ /dev/null @@ -1,99 +0,0 @@ -# -# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# -# @test -# @summary Tests MM getTotalSwapSpaceSize() api. -# @author Swamy V -# @bug 6252770 -# -# @run build GetTotalSwapSpaceSize -# @run shell TestTotalSwap.sh -# - -# -# This test tests the actual swap size on linux and solaris. -# On windows this is just a sanity check and correct size should -# be checked manually: -# -# Windows NT/XP/2000: -# 1. Run Start->Accessories->System Tools->System Information. -# 2. The value (reported in Kbytes) is in the "Page File Space" entry -# Windows 98/ME: -# Unknown. -# - - -#set -x - -#Set appropriate jdk -# - -if [ ! -z "${TESTJAVA}" ] ; then - jdk="$TESTJAVA" -else - echo "--Error: TESTJAVA must be defined as the pathname of a jdk to test." - exit 1 -fi - -runOne() -{ - echo "runOne $@" - $TESTJAVA/bin/java ${TESTVMOPTS} -classpath $TESTCLASSES $@ || exit 3 -} - -solaris_swap_size() -{ - total_swap=0 - for i in `/usr/sbin/swap -l | awk '{print $4}' | grep -v blocks` - do - # swap -l returns size in blocks of 512 bytes. - total_swap=`expr $i \* 512 + $total_swap` - done -} - -# Test GetTotalSwapSpaceSize if we are running on Unix -total_swap=0 -case `uname -s` in - SunOS ) - solaris_swap_size - runOne GetTotalSwapSpaceSize $total_swap - ;; - Linux ) - total_swap=`free -b | grep -i swap | awk '{print $2}'` - runOne GetTotalSwapSpaceSize $total_swap - ;; - Darwin ) - # $ sysctl -n vm.swapusage - # total = 8192.00M used = 7471.11M free = 720.89M (encrypted) - swap=`/usr/sbin/sysctl -n vm.swapusage | awk '{ print $3 }' | awk -F . '{ print $1 }'` || exit 2 - total_swap=`expr $swap \* 1024 \* 1024` || exit 2 - runOne GetTotalSwapSpaceSize $total_swap - ;; - * ) - runOne GetTotalSwapSpaceSize "sanity-only" - ;; -esac - -exit 0 - From e0e6ce31fd26ba66662a9152fd60368c19ce9dc1 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Fri, 20 Feb 2015 18:32:10 +0300 Subject: [PATCH 02/29] 8073479: Replace obj.getClass hacks with Objects.requireNonNull Reviewed-by: dfuchs, plevart, vlivanov --- .../java/lang/invoke/DirectMethodHandle.java | 7 +++---- .../classes/java/lang/invoke/MemberName.java | 6 +++--- .../classes/java/lang/invoke/MethodHandle.java | 8 +++----- .../classes/java/lang/invoke/MethodHandles.java | 17 +++++++++-------- .../java/lang/invoke/MutableCallSite.java | 3 ++- .../classes/java/util/logging/Handler.java | 5 ++--- .../classes/java/util/logging/LogRecord.java | 4 +--- .../share/classes/java/util/logging/Logger.java | 4 ++-- .../java/lang/invoke/8009222/Test8009222.java | 6 +++--- .../pack200-verifier/src/xmlkit/XMLKit.java | 8 ++++---- 10 files changed, 32 insertions(+), 36 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java index fe54fd21492..7cdb8c5e982 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java @@ -35,6 +35,7 @@ import static java.lang.invoke.MethodTypeForm.*; import static java.lang.invoke.MethodHandleStatics.*; import java.lang.ref.WeakReference; import java.lang.reflect.Field; +import java.util.Objects; import sun.invoke.util.ValueConversions; import sun.invoke.util.VerifyType; import sun.invoke.util.Wrapper; @@ -439,8 +440,7 @@ class DirectMethodHandle extends MethodHandle { // Therefore, the only remaining check is for null. // Since this check is *not* guaranteed by Unsafe.getInt // and its siblings, we need to make an explicit one here. - obj.getClass(); // maybe throw NPE - return obj; + return Objects.requireNonNull(obj); } /** This subclass handles static field references. */ @@ -468,8 +468,7 @@ class DirectMethodHandle extends MethodHandle { @ForceInline /*non-public*/ static Object nullCheck(Object obj) { - obj.getClass(); - return obj; + return Objects.requireNonNull(obj); } @ForceInline diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java b/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java index d4634c84a8e..6622bb37738 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java @@ -521,7 +521,7 @@ import java.util.Objects; } @SuppressWarnings("LeakingThisInConstructor") public MemberName(Method m, boolean wantSpecial) { - m.getClass(); // NPE check + Objects.requireNonNull(m); // fill in vmtarget, vmindex while we have m in hand: MethodHandleNatives.init(this, m); if (clazz == null) { // MHN.init failed @@ -600,7 +600,7 @@ import java.util.Objects; /** Create a name for the given reflected constructor. The resulting name will be in a resolved state. */ @SuppressWarnings("LeakingThisInConstructor") public MemberName(Constructor ctor) { - ctor.getClass(); // NPE check + Objects.requireNonNull(ctor); // fill in vmtarget, vmindex while we have ctor in hand: MethodHandleNatives.init(this, ctor); assert(isResolved() && this.clazz != null); @@ -615,7 +615,7 @@ import java.util.Objects; } @SuppressWarnings("LeakingThisInConstructor") public MemberName(Field fld, boolean makeSetter) { - fld.getClass(); // NPE check + Objects.requireNonNull(fld); // fill in vmtarget, vmindex while we have fld in hand: MethodHandleNatives.init(this, fld); assert(isResolved() && this.clazz != null); diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java index 61c114e54b1..cb621b60e82 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java @@ -453,10 +453,8 @@ public abstract class MethodHandle { */ // @param type type (permanently assigned) of the new method handle /*non-public*/ MethodHandle(MethodType type, LambdaForm form) { - type.getClass(); // explicit NPE - form.getClass(); // explicit NPE - this.type = type; - this.form = form.uncustomize(); + this.type = Objects.requireNonNull(type); + this.form = Objects.requireNonNull(form).uncustomize(); this.form.prepare(); // TO DO: Try to delay this step until just before invocation. } @@ -1171,7 +1169,7 @@ assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0))); * @see #asFixedArity */ public MethodHandle asVarargsCollector(Class arrayType) { - arrayType.getClass(); // explicit NPE + Objects.requireNonNull(arrayType); boolean lastMatch = asCollectorChecks(arrayType, 0); if (isVarargsCollector() && lastMatch) return this; diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java index eda6a6d27df..41a0054db7a 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java @@ -29,6 +29,7 @@ import java.lang.reflect.*; import java.util.BitSet; import java.util.List; import java.util.Arrays; +import java.util.Objects; import sun.invoke.util.ValueConversions; import sun.invoke.util.VerifyAccess; @@ -632,7 +633,7 @@ public class MethodHandles { * @throws NullPointerException if the argument is null */ public Lookup in(Class requestedLookupClass) { - requestedLookupClass.getClass(); // null check + Objects.requireNonNull(requestedLookupClass); if (allowedModes == TRUSTED) // IMPL_LOOKUP can make any lookup at all return new Lookup(requestedLookupClass, ALL_MODES); if (requestedLookupClass == this.lookupClass) @@ -1367,16 +1368,16 @@ return mh1; MemberName resolveOrFail(byte refKind, Class refc, String name, Class type) throws NoSuchFieldException, IllegalAccessException { checkSymbolicClass(refc); // do this before attempting to resolve - name.getClass(); // NPE - type.getClass(); // NPE + Objects.requireNonNull(name); + Objects.requireNonNull(type); return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), NoSuchFieldException.class); } MemberName resolveOrFail(byte refKind, Class refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException { checkSymbolicClass(refc); // do this before attempting to resolve - name.getClass(); // NPE - type.getClass(); // NPE + Objects.requireNonNull(name); + Objects.requireNonNull(type); checkMethodName(refKind, name); // NPE check on name return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), NoSuchMethodException.class); @@ -1384,14 +1385,14 @@ return mh1; MemberName resolveOrFail(byte refKind, MemberName member) throws ReflectiveOperationException { checkSymbolicClass(member.getDeclaringClass()); // do this before attempting to resolve - member.getName().getClass(); // NPE - member.getType().getClass(); // NPE + Objects.requireNonNull(member.getName()); + Objects.requireNonNull(member.getType()); return IMPL_NAMES.resolveOrFail(refKind, member, lookupClassOrNull(), ReflectiveOperationException.class); } void checkSymbolicClass(Class refc) throws IllegalAccessException { - refc.getClass(); // NPE + Objects.requireNonNull(refc); Class caller = lookupClassOrNull(); if (caller != null && !VerifyAccess.isClassAccessible(refc, caller, allowedModes)) throw new MemberName(refc).makeAccessException("symbolic reference class is not public", this); diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MutableCallSite.java b/jdk/src/java.base/share/classes/java/lang/invoke/MutableCallSite.java index c5f74500dd7..6e5d350495d 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MutableCallSite.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MutableCallSite.java @@ -25,6 +25,7 @@ package java.lang.invoke; +import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; /** @@ -275,7 +276,7 @@ public class MutableCallSite extends CallSite { if (sites.length == 0) return; STORE_BARRIER.lazySet(0); for (MutableCallSite site : sites) { - site.getClass(); // trigger NPE on first null + Objects.requireNonNull(site); // trigger NPE on first null } // FIXME: NYI } diff --git a/jdk/src/java.logging/share/classes/java/util/logging/Handler.java b/jdk/src/java.logging/share/classes/java/util/logging/Handler.java index ce198509614..6a44b45465f 100644 --- a/jdk/src/java.logging/share/classes/java/util/logging/Handler.java +++ b/jdk/src/java.logging/share/classes/java/util/logging/Handler.java @@ -26,6 +26,7 @@ package java.util.logging; +import java.util.Objects; import java.io.UnsupportedEncodingException; import java.security.AccessController; import java.security.PrivilegedAction; @@ -165,9 +166,7 @@ public abstract class Handler { */ public synchronized void setFormatter(Formatter newFormatter) throws SecurityException { checkPermission(); - // Check for a null pointer: - newFormatter.getClass(); - formatter = newFormatter; + formatter = Objects.requireNonNull(newFormatter); } /** diff --git a/jdk/src/java.logging/share/classes/java/util/logging/LogRecord.java b/jdk/src/java.logging/share/classes/java/util/logging/LogRecord.java index 1ea4d72008d..831f362f52a 100644 --- a/jdk/src/java.logging/share/classes/java/util/logging/LogRecord.java +++ b/jdk/src/java.logging/share/classes/java/util/logging/LogRecord.java @@ -175,9 +175,7 @@ public class LogRecord implements java.io.Serializable { * @param msg the raw non-localized logging message (may be null) */ public LogRecord(Level level, String msg) { - // Make sure level isn't null, by calling random method. - level.getClass(); - this.level = level; + this.level = Objects.requireNonNull(level); message = msg; // Assign a thread ID and a unique sequence number. sequenceNumber = globalSequenceNumber.getAndIncrement(); diff --git a/jdk/src/java.logging/share/classes/java/util/logging/Logger.java b/jdk/src/java.logging/share/classes/java/util/logging/Logger.java index fc4101f20f4..8a50a433acb 100644 --- a/jdk/src/java.logging/share/classes/java/util/logging/Logger.java +++ b/jdk/src/java.logging/share/classes/java/util/logging/Logger.java @@ -33,6 +33,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.Locale; import java.util.MissingResourceException; +import java.util.Objects; import java.util.ResourceBundle; import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Supplier; @@ -1746,8 +1747,7 @@ public class Logger { * does not have LoggingPermission("control"). */ public void addHandler(Handler handler) throws SecurityException { - // Check for null handler - handler.getClass(); + Objects.requireNonNull(handler); checkPermission(); handlers.add(handler); } diff --git a/jdk/test/java/lang/invoke/8009222/Test8009222.java b/jdk/test/java/lang/invoke/8009222/Test8009222.java index 212e09a00cd..711969387ed 100644 --- a/jdk/test/java/lang/invoke/8009222/Test8009222.java +++ b/jdk/test/java/lang/invoke/8009222/Test8009222.java @@ -33,6 +33,7 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; +import java.util.Objects; interface Intf { static int i = 0; @@ -40,9 +41,8 @@ interface Intf { public class Test8009222 { public static void main(String[] args) throws Exception { - MethodHandles.lookup() - .findStaticGetter(Intf.class, "i", int.class) - .getClass(); // null check + Objects.requireNonNull(MethodHandles.lookup() + .findStaticGetter(Intf.class, "i", int.class)); System.out.println("TEST PASSED"); } diff --git a/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/XMLKit.java b/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/XMLKit.java index f1f3bd46208..7609386b4d2 100644 --- a/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/XMLKit.java +++ b/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/XMLKit.java @@ -739,7 +739,7 @@ public abstract class XMLKit { if (i >= size) { badIndex(i); } - e.getClass(); // null check + Objects.requireNonNull(e); checkNotFrozen(); Object old = parts[i]; setRaw(i, e); @@ -861,7 +861,7 @@ public abstract class XMLKit { public void add(int i, Object e) { // (The shape of this method is tweaked for common cases.) - e.getClass(); // force a null check on e + Objects.requireNonNull(e); if (hasNulls(1 + NEED_SLOP)) { // Common case: Have some slop space. if (i == size) { @@ -2943,7 +2943,7 @@ public abstract class XMLKit { } public static Filter elementFilter(final Collection nameSet) { - nameSet.getClass(); // null check + Objects.requireNonNull(nameSet); return new ElementFilter() { @Override @@ -3299,7 +3299,7 @@ public abstract class XMLKit { } public static Filter replaceInTree(Filter f) { - f.getClass(); // null check + Objects.requireNonNull(f); return replaceInTree(f, null); } From 16989e7b17cf273410440d46a38f66989109c2e9 Mon Sep 17 00:00:00 2001 From: Claes Redestad Date: Sat, 21 Feb 2015 13:46:24 +0100 Subject: [PATCH 03/29] 8068790: ZipEntry/JarEntry.setCreation/LastAccessTime(null) don't throw NPE as specified Reviewed-by: coffeys, sherman --- .../share/classes/java/util/zip/ZipEntry.java | 9 +++---- jdk/test/java/util/zip/TestExtraTime.java | 26 ++++++++++++++++++- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/util/zip/ZipEntry.java b/jdk/src/java.base/share/classes/java/util/zip/ZipEntry.java index 3f958c48816..1e32e74ad1c 100644 --- a/jdk/src/java.base/share/classes/java/util/zip/ZipEntry.java +++ b/jdk/src/java.base/share/classes/java/util/zip/ZipEntry.java @@ -180,8 +180,7 @@ class ZipEntry implements ZipConstants, Cloneable { * @since 1.8 */ public ZipEntry setLastModifiedTime(FileTime time) { - Objects.requireNonNull(name, "time"); - this.mtime = time; + this.mtime = Objects.requireNonNull(time, "lastModifiedTime"); this.time = time.to(TimeUnit.MILLISECONDS); return this; } @@ -227,8 +226,7 @@ class ZipEntry implements ZipConstants, Cloneable { * @since 1.8 */ public ZipEntry setLastAccessTime(FileTime time) { - Objects.requireNonNull(name, "time"); - this.atime = time; + this.atime = Objects.requireNonNull(time, "lastAccessTime"); return this; } @@ -265,8 +263,7 @@ class ZipEntry implements ZipConstants, Cloneable { * @since 1.8 */ public ZipEntry setCreationTime(FileTime time) { - Objects.requireNonNull(name, "time"); - this.ctime = time; + this.ctime = Objects.requireNonNull(time, "creationTime"); return this; } diff --git a/jdk/test/java/util/zip/TestExtraTime.java b/jdk/test/java/util/zip/TestExtraTime.java index b96c85f7c02..fcf75a153b0 100644 --- a/jdk/test/java/util/zip/TestExtraTime.java +++ b/jdk/test/java/util/zip/TestExtraTime.java @@ -23,7 +23,7 @@ /** * @test - * @bug 4759491 6303183 7012868 8015666 8023713 + * @bug 4759491 6303183 7012868 8015666 8023713 8068790 * @summary Test ZOS and ZIS timestamp in extra field correctly */ @@ -69,6 +69,8 @@ public class TestExtraTime { test(mtime, atime, ctime, tz, extra); } } + + testNullHandling(); } static void test(FileTime mtime, FileTime atime, FileTime ctime, @@ -154,4 +156,26 @@ public class TestExtraTime { } } } + + static void testNullHandling() { + ZipEntry ze = new ZipEntry("TestExtraTime.java"); + try { + ze.setLastAccessTime(null); + throw new RuntimeException("setLastAccessTime(null) should throw NPE"); + } catch (NullPointerException ignored) { + // pass + } + try { + ze.setCreationTime(null); + throw new RuntimeException("setCreationTime(null) should throw NPE"); + } catch (NullPointerException ignored) { + // pass + } + try { + ze.setLastModifiedTime(null); + throw new RuntimeException("setLastModifiedTime(null) should throw NPE"); + } catch (NullPointerException ignored) { + // pass + } + } } From 414de033e0a73e2c839d5cc075b303e7642de806 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Mon, 23 Feb 2015 11:37:36 +0100 Subject: [PATCH 04/29] 8073498: Enhance GensrcProperties.gmk to allow an alternative source root Reviewed-by: tbell, mchung, ihse --- jdk/make/gensrc/GensrcProperties.gmk | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/jdk/make/gensrc/GensrcProperties.gmk b/jdk/make/gensrc/GensrcProperties.gmk index fc7504cddfd..dc78489e0b9 100644 --- a/jdk/make/gensrc/GensrcProperties.gmk +++ b/jdk/make/gensrc/GensrcProperties.gmk @@ -53,15 +53,21 @@ endef # Param 1 - Variable to add targets to, must not contain space # Param 2 - Properties files to process # Param 3 - The super class for the generated classes +# Param 4 - Module path root, defaults to $(JDK_TOPDIR)/src define SetupCompileProperties $1_SRCS := $2 $1_CLASS := $3 + $1_MODULE_PATH_ROOT := $4 + + ifeq ($$($1_MODULE_PATH_ROOT), ) + $1_MODULE_PATH_ROOT := $(JDK_TOPDIR)/src + endif # Convert .../src//share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties # to .../support/gensrc//com/sun/tools/javac/resources/javac_zh_CN.java # Strip away prefix and suffix, leaving for example only: # "/share/classes/com/sun/tools/javac/resources/javac_zh_CN" - $1_JAVAS := $$(patsubst $(JDK_TOPDIR)/src/%, \ + $1_JAVAS := $$(patsubst $$($1_MODULE_PATH_ROOT)/%, \ $(SUPPORT_OUTPUTDIR)/gensrc/%, \ $$(patsubst %.properties, %.java, \ $$(subst /$(OPENJDK_TARGET_OS)/classes,, \ From b7d07021882ab0a14cc703932b533d8566b9cfea Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Mon, 23 Feb 2015 15:48:20 +0000 Subject: [PATCH 05/29] 8064924: Update java.net.URL to work with modules Reviewed-by: alanb, plevart, psandoz --- .../java.base/share/classes/java/net/URL.java | 237 ++++++++----- .../java/net/URLStreamHandlerFactory.java | 4 +- .../share/classes/java/net/package-info.java | 12 +- .../net/spi/URLStreamHandlerProvider.java | 67 ++++ .../classes/java/net/spi/package-info.java | 35 ++ .../spi/URLStreamHandlerProvider/Basic.java | 313 ++++++++++++++++++ .../spi/URLStreamHandlerProvider/Child.java | 45 +++ .../bad.provider.template | 41 +++ .../spi/URLStreamHandlerProvider/basic.policy | 27 ++ .../provider.template | 50 +++ .../net/ssl/FixingJavadocs/ComURLNulls.java | 15 +- .../https/NewImpl/ComHTTPSConnection.java | 14 +- .../https/NewImpl/ComHostnameVerifier.java | 14 +- 13 files changed, 770 insertions(+), 104 deletions(-) create mode 100644 jdk/src/java.base/share/classes/java/net/spi/URLStreamHandlerProvider.java create mode 100644 jdk/src/java.base/share/classes/java/net/spi/package-info.java create mode 100644 jdk/test/java/net/spi/URLStreamHandlerProvider/Basic.java create mode 100644 jdk/test/java/net/spi/URLStreamHandlerProvider/Child.java create mode 100644 jdk/test/java/net/spi/URLStreamHandlerProvider/bad.provider.template create mode 100644 jdk/test/java/net/spi/URLStreamHandlerProvider/basic.policy create mode 100644 jdk/test/java/net/spi/URLStreamHandlerProvider/provider.template diff --git a/jdk/src/java.base/share/classes/java/net/URL.java b/jdk/src/java.base/share/classes/java/net/URL.java index 6d50d1c4262..94d68a2fe71 100644 --- a/jdk/src/java.base/share/classes/java/net/URL.java +++ b/jdk/src/java.base/share/classes/java/net/URL.java @@ -27,8 +27,15 @@ package java.net; import java.io.IOException; import java.io.InputStream; +import java.net.spi.URLStreamHandlerProvider; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Hashtable; -import java.util.StringTokenizer; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.ServiceConfigurationError; +import java.util.ServiceLoader; + import sun.security.util.SecurityConstants; /** @@ -248,23 +255,19 @@ public final class URL implements java.io.Serializable { * stream protocol handler. *
  • If no {@code URLStreamHandlerFactory} has yet been set up, * or if the factory's {@code createURLStreamHandler} method - * returns {@code null}, then the constructor finds the - * value of the system property: - *
    -     *         java.protocol.handler.pkgs
    -     *     
    - * If the value of that system property is not {@code null}, - * it is interpreted as a list of packages separated by a vertical - * slash character '{@code |}'. The constructor tries to load - * the class named: - *
    -     *         <package>.<protocol>.Handler
    -     *     
    - * where <package> is replaced by the name of the package - * and <protocol> is replaced by the name of the protocol. - * If this class does not exist, or if the class exists but it is not - * a subclass of {@code URLStreamHandler}, then the next package - * in the list is tried. + * returns {@code null}, then the {@linkplain java.util.ServiceLoader + * ServiceLoader} mechanism is used to locate {@linkplain + * java.net.spi.URLStreamHandlerProvider URLStreamHandlerProvider} + * implementations using the system class + * loader. The order that providers are located is implementation + * specific, and an implementation is free to cache the located + * providers. A {@linkplain java.util.ServiceConfigurationError + * ServiceConfigurationError}, {@code Error} or {@code RuntimeException} + * thrown from the {@code createURLStreamHandler}, if encountered, will + * be propagated to the calling thread. The {@code + * createURLStreamHandler} method of each provider, if instantiated, is + * invoked, with the protocol string, until a provider returns non-null, + * or all providers have been exhausted. *
  • If the previous step fails to find a protocol handler, then the * constructor tries to load a built-in protocol handler. * If this class does not exist, or if the class exists but it is not a @@ -277,8 +280,12 @@ public final class URL implements java.io.Serializable { *
          *     http, https, file, and jar
          * 
    - * Protocol handlers for additional protocols may also be - * available. + * Protocol handlers for additional protocols may also be available. + * Some protocol handlers, for example those used for loading platform + * classes or classes on the class path, may not be overridden. The details + * of such restrictions, and when those restrictions apply (during + * initialization of the runtime for example), are implementation specific + * and therefore not specified * *

    No validation of the inputs is performed by this constructor. * @@ -1107,20 +1114,115 @@ public final class URL implements java.io.Serializable { } handlers.clear(); - // ensure the core protocol handlers are loaded before setting - // a custom URLStreamHandlerFactory - ensureHandlersLoaded("jrt", "jar", "file"); - // safe publication of URLStreamHandlerFactory with volatile write factory = fac; } } + private static final URLStreamHandlerFactory defaultFactory = new DefaultFactory(); + + private static class DefaultFactory implements URLStreamHandlerFactory { + private static String PREFIX = "sun.net.www.protocol"; + + public URLStreamHandler createURLStreamHandler(String protocol) { + String name = PREFIX + "." + protocol + ".Handler"; + try { + Class c = Class.forName(name); + return (URLStreamHandler)c.newInstance(); + } catch (ClassNotFoundException x) { + // ignore + } catch (Exception e) { + // For compatibility, all Exceptions are ignored. + // any number of exceptions can get thrown here + } + return null; + } + } + + private static Iterator providers() { + return new Iterator() { + + ClassLoader cl = ClassLoader.getSystemClassLoader(); + ServiceLoader sl = + ServiceLoader.load(URLStreamHandlerProvider.class, cl); + Iterator i = sl.iterator(); + + URLStreamHandlerProvider next = null; + + private boolean getNext() { + while (next == null) { + try { + if (!i.hasNext()) + return false; + next = i.next(); + } catch (ServiceConfigurationError sce) { + if (sce.getCause() instanceof SecurityException) { + // Ignore security exceptions + continue; + } + throw sce; + } + } + return true; + } + + public boolean hasNext() { + return getNext(); + } + + public URLStreamHandlerProvider next() { + if (!getNext()) + throw new NoSuchElementException(); + URLStreamHandlerProvider n = next; + next = null; + return n; + } + }; + } + + // Thread-local gate to prevent recursive provider lookups + private static ThreadLocal gate = new ThreadLocal<>(); + + private static URLStreamHandler lookupViaProviders(final String protocol) { + if (!sun.misc.VM.isBooted()) + return null; + + if (gate.get() != null) + throw new Error("Circular loading of URL stream handler providers detected"); + + gate.set(gate); + try { + return AccessController.doPrivileged( + new PrivilegedAction() { + public URLStreamHandler run() { + Iterator itr = providers(); + while (itr.hasNext()) { + URLStreamHandlerProvider f = itr.next(); + URLStreamHandler h = f.createURLStreamHandler(protocol); + if (h != null) + return h; + } + return null; + } + }); + } finally { + gate.set(null); + } + } + + private static final String[] NON_OVERRIDEABLE_PROTOCOLS = {"file", "jrt"}; + private static boolean isOverrideable(String protocol) { + for (String p : NON_OVERRIDEABLE_PROTOCOLS) + if (protocol.equalsIgnoreCase(p)) + return false; + return true; + } + /** * A table of protocol handlers. */ static Hashtable handlers = new Hashtable<>(); - private static Object streamHandlerLock = new Object(); + private static final Object streamHandlerLock = new Object(); /** * Returns the Stream Handler. @@ -1129,66 +1231,33 @@ public final class URL implements java.io.Serializable { static URLStreamHandler getURLStreamHandler(String protocol) { URLStreamHandler handler = handlers.get(protocol); - if (handler == null) { - boolean checkedWithFactory = false; + if (handler != null) { + return handler; + } + URLStreamHandlerFactory fac; + boolean checkedWithFactory = false; + + if (isOverrideable(protocol)) { // Use the factory (if any). Volatile read makes // URLStreamHandlerFactory appear fully initialized to current thread. - URLStreamHandlerFactory fac = factory; + fac = factory; if (fac != null) { handler = fac.createURLStreamHandler(protocol); checkedWithFactory = true; } - // Try java protocol handler if (handler == null) { - String packagePrefixList = null; - - packagePrefixList - = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction( - protocolPathProp,"")); - if (packagePrefixList != "") { - packagePrefixList += "|"; - } - - // REMIND: decide whether to allow the "null" class prefix - // or not. - packagePrefixList += "sun.net.www.protocol"; - - StringTokenizer packagePrefixIter = - new StringTokenizer(packagePrefixList, "|"); - - while (handler == null && - packagePrefixIter.hasMoreTokens()) { - - String packagePrefix = - packagePrefixIter.nextToken().trim(); - try { - String clsName = packagePrefix + "." + protocol + - ".Handler"; - Class cls = null; - try { - cls = Class.forName(clsName); - } catch (ClassNotFoundException e) { - ClassLoader cl = ClassLoader.getSystemClassLoader(); - if (cl != null) { - cls = cl.loadClass(clsName); - } - } - if (cls != null) { - handler = - (URLStreamHandler)cls.newInstance(); - } - } catch (Exception e) { - // any number of exceptions can get thrown here - } - } + handler = lookupViaProviders(protocol); } + } - synchronized (streamHandlerLock) { - + synchronized (streamHandlerLock) { + if (handler == null) { + // Try the built-in protocol handler + handler = defaultFactory.createURLStreamHandler(protocol); + } else { URLStreamHandler handler2 = null; // Check again with hashtable just in case another @@ -1202,7 +1271,7 @@ public final class URL implements java.io.Serializable { // Check with factory if another thread set a // factory since our last check if (!checkedWithFactory && (fac = factory) != null) { - handler2 = fac.createURLStreamHandler(protocol); + handler2 = fac.createURLStreamHandler(protocol); } if (handler2 != null) { @@ -1211,29 +1280,17 @@ public final class URL implements java.io.Serializable { // this thread created. handler = handler2; } + } - // Insert this handler into the hashtable - if (handler != null) { - handlers.put(protocol, handler); - } - + // Insert this handler into the hashtable + if (handler != null) { + handlers.put(protocol, handler); } } return handler; - } - /** - * Ensures that the given protocol handlers are loaded - */ - private static void ensureHandlersLoaded(String... protocols) { - for (String protocol: protocols) { - getURLStreamHandler(protocol); - } - } - - /** * WriteObject is called to save the state of the URL to an * ObjectOutputStream. The handler is not saved since it is diff --git a/jdk/src/java.base/share/classes/java/net/URLStreamHandlerFactory.java b/jdk/src/java.base/share/classes/java/net/URLStreamHandlerFactory.java index 0b3c86275c1..fd42613a1cf 100644 --- a/jdk/src/java.base/share/classes/java/net/URLStreamHandlerFactory.java +++ b/jdk/src/java.base/share/classes/java/net/URLStreamHandlerFactory.java @@ -44,7 +44,9 @@ public interface URLStreamHandlerFactory { * * @param protocol the protocol ("{@code ftp}", * "{@code http}", "{@code nntp}", etc.). - * @return a {@code URLStreamHandler} for the specific protocol. + * @return a {@code URLStreamHandler} for the specific protocol, or {@code + * null} if this factory cannot create a handler for the specific + * protocol * @see java.net.URLStreamHandler */ URLStreamHandler createURLStreamHandler(String protocol); diff --git a/jdk/src/java.base/share/classes/java/net/package-info.java b/jdk/src/java.base/share/classes/java/net/package-info.java index ce812d73282..2279cca479f 100644 --- a/jdk/src/java.base/share/classes/java/net/package-info.java +++ b/jdk/src/java.base/share/classes/java/net/package-info.java @@ -143,13 +143,11 @@ * a similar URL will try to instantiate the handler for the specified protocol; * if it doesn't exist an exception will be thrown. *

    By default the protocol handlers are loaded dynamically from the default - * location. It is, however, possible to add to the search path by setting - * the {@code java.protocol.handler.pkgs} system property. For instance if - * it is set to {@code myapp.protocols}, then the URL code will try, in the - * case of http, first to load {@code myapp.protocols.http.Handler}, then, - * if this fails, {@code http.Handler} from the default location. - *

    Note that the Handler class has to be a subclass of the abstract - * class {@link java.net.URLStreamHandler}.

    + * location. It is, however, possible to deploy additional protocols handlers + * as {@link java.util.ServiceLoader services}. Service providers of type + * {@linkplain java.net.spi.URLStreamHandlerProvider} are located at + * runtime, as specified in the {@linkplain + * java.net.URL#URL(String,String,int,String) URL constructor}. *

    Additional Specification

    * * *

    Synchronization Statistics

    @@ -78,7 +80,7 @@ import static java.lang.Thread.State.*; * the system, not for synchronization control. * *

    MXBean Mapping

    - * ThreadInfo is mapped to a {@link CompositeData CompositeData} + * {@code ThreadInfo} is mapped to a {@link CompositeData CompositeData} * with attributes as specified in * the {@link #from from} method. * @@ -100,9 +102,11 @@ public class ThreadInfo { private String lockName; private long lockOwnerId; private String lockOwnerName; + private boolean daemon; private boolean inNative; private boolean suspended; private Thread.State threadState; + private int priority; private StackTraceElement[] stackTrace; private MonitorInfo[] lockedMonitors; private LockInfo[] lockedSynchronizers; @@ -229,6 +233,8 @@ public class ThreadInfo { this.blockedTime = blockedTime; this.waitedCount = waitedCount; this.waitedTime = waitedTime; + this.daemon = t.isDaemon(); + this.priority = t.getPriority(); if (lockObj == null) { this.lock = null; @@ -256,7 +262,7 @@ public class ThreadInfo { } /* - * Constructs a ThreadInfo object from a + * Constructs a {@code ThreadInfo} object from a * {@link CompositeData CompositeData}. */ private ThreadInfo(CompositeData cd) { @@ -277,7 +283,7 @@ public class ThreadInfo { stackTrace = ticd.stackTrace(); // 6.0 attributes - if (ticd.isCurrentVersion()) { + if (ticd.hasV6()) { lock = ticd.lockInfo(); lockedMonitors = ticd.lockedMonitors(); lockedSynchronizers = ticd.lockedSynchronizers(); @@ -300,10 +306,20 @@ public class ThreadInfo { lockedMonitors = EMPTY_MONITORS; lockedSynchronizers = EMPTY_SYNCS; } + + // 9.0 attributes + if (ticd.isCurrentVersion()) { + daemon = ticd.isDaemon(); + priority = ticd.getPriority(); + } else { + // Not ideal, but unclear what else we can do. + daemon = false; + priority = Thread.NORM_PRIORITY; + } } /** - * Returns the ID of the thread associated with this ThreadInfo. + * Returns the ID of the thread associated with this {@code ThreadInfo}. * * @return the ID of the associated thread. */ @@ -312,7 +328,7 @@ public class ThreadInfo { } /** - * Returns the name of the thread associated with this ThreadInfo. + * Returns the name of the thread associated with this {@code ThreadInfo}. * * @return the name of the associated thread. */ @@ -321,9 +337,9 @@ public class ThreadInfo { } /** - * Returns the state of the thread associated with this ThreadInfo. + * Returns the state of the thread associated with this {@code ThreadInfo}. * - * @return Thread.State of the associated thread. + * @return {@code Thread.State} of the associated thread. */ public Thread.State getThreadState() { return threadState; @@ -331,13 +347,13 @@ public class ThreadInfo { /** * Returns the approximate accumulated elapsed time (in milliseconds) - * that the thread associated with this ThreadInfo + * that the thread associated with this {@code ThreadInfo} * has blocked to enter or reenter a monitor * since thread contention monitoring is enabled. * I.e. the total accumulated time the thread has been in the * {@link java.lang.Thread.State#BLOCKED BLOCKED} state since thread * contention monitoring was last enabled. - * This method returns -1 if thread contention monitoring + * This method returns {@code -1} if thread contention monitoring * is disabled. * *

    The Java virtual machine may measure the time with a high @@ -345,8 +361,8 @@ public class ThreadInfo { * the thread contention monitoring is reenabled. * * @return the approximate accumulated elapsed time in milliseconds - * that a thread entered the BLOCKED state; - * -1 if thread contention monitoring is disabled. + * that a thread entered the {@code BLOCKED} state; + * {@code -1} if thread contention monitoring is disabled. * * @throws java.lang.UnsupportedOperationException if the Java * virtual machine does not support this operation. @@ -360,13 +376,13 @@ public class ThreadInfo { /** * Returns the total number of times that - * the thread associated with this ThreadInfo + * the thread associated with this {@code ThreadInfo} * blocked to enter or reenter a monitor. * I.e. the number of times a thread has been in the * {@link java.lang.Thread.State#BLOCKED BLOCKED} state. * * @return the total number of times that the thread - * entered the BLOCKED state. + * entered the {@code BLOCKED} state. */ public long getBlockedCount() { return blockedCount; @@ -374,14 +390,14 @@ public class ThreadInfo { /** * Returns the approximate accumulated elapsed time (in milliseconds) - * that the thread associated with this ThreadInfo + * that the thread associated with this {@code ThreadInfo} * has waited for notification * since thread contention monitoring is enabled. * I.e. the total accumulated time the thread has been in the * {@link java.lang.Thread.State#WAITING WAITING} * or {@link java.lang.Thread.State#TIMED_WAITING TIMED_WAITING} state * since thread contention monitoring is enabled. - * This method returns -1 if thread contention monitoring + * This method returns {@code -1} if thread contention monitoring * is disabled. * *

    The Java virtual machine may measure the time with a high @@ -389,9 +405,9 @@ public class ThreadInfo { * the thread contention monitoring is reenabled. * * @return the approximate accumulated elapsed time in milliseconds - * that a thread has been in the WAITING or - * TIMED_WAITING state; - * -1 if thread contention monitoring is disabled. + * that a thread has been in the {@code WAITING} or + * {@code TIMED_WAITING} state; + * {@code -1} if thread contention monitoring is disabled. * * @throws java.lang.UnsupportedOperationException if the Java * virtual machine does not support this operation. @@ -405,29 +421,29 @@ public class ThreadInfo { /** * Returns the total number of times that - * the thread associated with this ThreadInfo + * the thread associated with this {@code ThreadInfo} * waited for notification. * I.e. the number of times that a thread has been * in the {@link java.lang.Thread.State#WAITING WAITING} * or {@link java.lang.Thread.State#TIMED_WAITING TIMED_WAITING} state. * * @return the total number of times that the thread - * was in the WAITING or TIMED_WAITING state. + * was in the {@code WAITING} or {@code TIMED_WAITING} state. */ public long getWaitedCount() { return waitedCount; } /** - * Returns the LockInfo of an object for which - * the thread associated with this ThreadInfo + * Returns the {@code LockInfo} of an object for which + * the thread associated with this {@code ThreadInfo} * is blocked waiting. * A thread can be blocked waiting for one of the following: *

      *
    • an object monitor to be acquired for entering or reentering * a synchronization block/method. *
      The thread is in the {@link java.lang.Thread.State#BLOCKED BLOCKED} - * state waiting to enter the synchronized statement + * state waiting to enter the {@code synchronized} statement * or method. *
    • *
    • an object monitor to be notified by another thread. @@ -448,11 +464,11 @@ public class ThreadInfo { * or a {@link java.util.concurrent.locks.Condition Condition}.
    • *
    * - *

    This method returns null if the thread is not in any of + *

    This method returns {@code null} if the thread is not in any of * the above conditions. * - * @return LockInfo of an object for which the thread - * is blocked waiting if any; null otherwise. + * @return {@code LockInfo} of an object for which the thread + * is blocked waiting if any; {@code null} otherwise. * @since 1.6 */ public LockInfo getLockInfo() { @@ -462,19 +478,19 @@ public class ThreadInfo { /** * Returns the {@link LockInfo#toString string representation} * of an object for which the thread associated with this - * ThreadInfo is blocked waiting. + * {@code ThreadInfo} is blocked waiting. * This method is equivalent to calling: *

    *
          * getLockInfo().toString()
          * 
    * - *

    This method will return null if this thread is not blocked + *

    This method will return {@code null} if this thread is not blocked * waiting for any object or if the object is not owned by any thread. * * @return the string representation of the object on which * the thread is blocked if any; - * null otherwise. + * {@code null} otherwise. * * @see #getLockInfo */ @@ -484,14 +500,14 @@ public class ThreadInfo { /** * Returns the ID of the thread which owns the object - * for which the thread associated with this ThreadInfo + * for which the thread associated with this {@code ThreadInfo} * is blocked waiting. - * This method will return -1 if this thread is not blocked + * This method will return {@code -1} if this thread is not blocked * waiting for any object or if the object is not owned by any thread. * * @return the thread ID of the owner thread of the object * this thread is blocked on; - * -1 if this thread is not blocked + * {@code -1} if this thread is not blocked * or if the object is not owned by any thread. * * @see #getLockInfo @@ -502,14 +518,14 @@ public class ThreadInfo { /** * Returns the name of the thread which owns the object - * for which the thread associated with this ThreadInfo + * for which the thread associated with this {@code ThreadInfo} * is blocked waiting. - * This method will return null if this thread is not blocked + * This method will return {@code null} if this thread is not blocked * waiting for any object or if the object is not owned by any thread. * * @return the name of the thread that owns the object * this thread is blocked on; - * null if this thread is not blocked + * {@code null} if this thread is not blocked * or if the object is not owned by any thread. * * @see #getLockInfo @@ -520,7 +536,7 @@ public class ThreadInfo { /** * Returns the stack trace of the thread - * associated with this ThreadInfo. + * associated with this {@code ThreadInfo}. * If no stack trace was requested for this thread info, this method * will return a zero-length array. * If the returned array is of non-zero length then the first element of @@ -532,41 +548,66 @@ public class ThreadInfo { *

    Some Java virtual machines may, under some circumstances, omit one * or more stack frames from the stack trace. In the extreme case, * a virtual machine that has no stack trace information concerning - * the thread associated with this ThreadInfo + * the thread associated with this {@code ThreadInfo} * is permitted to return a zero-length array from this method. * - * @return an array of StackTraceElement objects of the thread. + * @return an array of {@code StackTraceElement} objects of the thread. */ public StackTraceElement[] getStackTrace() { return stackTrace; } /** - * Tests if the thread associated with this ThreadInfo - * is suspended. This method returns true if + * Tests if the thread associated with this {@code ThreadInfo} + * is suspended. This method returns {@code true} if * {@link Thread#suspend} has been called. * - * @return true if the thread is suspended; - * false otherwise. + * @return {@code true} if the thread is suspended; + * {@code false} otherwise. */ public boolean isSuspended() { return suspended; } /** - * Tests if the thread associated with this ThreadInfo + * Tests if the thread associated with this {@code ThreadInfo} * is executing native code via the Java Native Interface (JNI). * The JNI native code does not include * the virtual machine support code or the compiled native * code generated by the virtual machine. * - * @return true if the thread is executing native code; - * false otherwise. + * @return {@code true} if the thread is executing native code; + * {@code false} otherwise. */ public boolean isInNative() { return inNative; } + /** + * Tests if the thread associated with this {@code ThreadInfo} is + * a {@linkplain Thread#isDaemon daemon thread}. + * + * @return {@code true} if the thread is a daemon thread, + * {@code false} otherwise. + * @see Thread#isDaemon + * @since 1.9 + */ + public boolean isDaemon() { + return daemon; + } + + /** + * Returns the {@linkplain Thread#getPriority() thread priority} of the + * thread associated with this {@code ThreadInfo}. + * + * @return The priority of the thread associated with this + * {@code ThreadInfo}. + * @since 1.9 + */ + public int getPriority() { + return priority; + } + /** * Returns a string representation of this thread info. * The format of this string depends on the implementation. @@ -580,6 +621,8 @@ public class ThreadInfo { */ public String toString() { StringBuilder sb = new StringBuilder("\"" + getThreadName() + "\"" + + (daemon ? " daemon" : "") + + " prio=" + priority + " Id=" + getThreadId() + " " + getThreadState()); if (getLockName() != null) { @@ -647,9 +690,9 @@ public class ThreadInfo { private static final int MAX_FRAMES = 8; /** - * Returns a ThreadInfo object represented by the - * given CompositeData. - * The given CompositeData must contain the following attributes + * Returns a {@code ThreadInfo} object represented by the + * given {@code CompositeData}. + * The given {@code CompositeData} must contain the following attributes * unless otherwise specified below: *

    * @@ -659,67 +702,67 @@ public class ThreadInfo { * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * If {@code cd} does not contain this attribute, + * the {@code LockInfo} object will be constructed from + * the value of the {@code lockName} attribute. * * * - * + * * * * - * + * * * * - * + * * * * - * * * - * * * * - * * + * + * + * + * + * + * + * + * *
    threadIdjava.lang.Long{@code java.lang.Long}
    threadNamejava.lang.String{@code java.lang.String}
    threadStatejava.lang.String{@code java.lang.String}
    suspendedjava.lang.Boolean{@code java.lang.Boolean}
    inNativejava.lang.Boolean{@code java.lang.Boolean}
    blockedCountjava.lang.Long{@code java.lang.Long}
    blockedTimejava.lang.Long{@code java.lang.Long}
    waitedCountjava.lang.Long{@code java.lang.Long}
    waitedTimejava.lang.Long{@code java.lang.Long}
    lockInfojavax.management.openmbean.CompositeData + * {@code javax.management.openmbean.CompositeData} * - the mapped type for {@link LockInfo} as specified in the * {@link LockInfo#from} method. *

    - * If cd does not contain this attribute, - * the LockInfo object will be constructed from - * the value of the lockName attribute.

    lockNamejava.lang.String{@code java.lang.String}
    lockOwnerIdjava.lang.Long{@code java.lang.Long}
    lockOwnerNamejava.lang.String{@code java.lang.String}
    stackTracejavax.management.openmbean.CompositeData[] + * {@code javax.management.openmbean.CompositeData[]} *

    - * Each element is a CompositeData representing + * Each element is a {@code CompositeData} representing * StackTraceElement containing the following attributes: *

    * @@ -729,23 +772,23 @@ public class ThreadInfo { * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * *
    classNamejava.lang.String{@code java.lang.String}
    methodNamejava.lang.String{@code java.lang.String}
    fileNamejava.lang.String{@code java.lang.String}
    lineNumberjava.lang.Integer{@code java.lang.Integer}
    nativeMethodjava.lang.Boolean{@code java.lang.Boolean}
    *
    @@ -753,35 +796,43 @@ public class ThreadInfo { *
    lockedMonitorsjavax.management.openmbean.CompositeData[] + * {@code javax.management.openmbean.CompositeData[]} * whose element type is the mapped type for * {@link MonitorInfo} as specified in the * {@link MonitorInfo#from Monitor.from} method. *

    - * If cd does not contain this attribute, + * If {@code cd} does not contain this attribute, * this attribute will be set to an empty array.

    lockedSynchronizersjavax.management.openmbean.CompositeData[] + * {@code javax.management.openmbean.CompositeData[]} * whose element type is the mapped type for * {@link LockInfo} as specified in the {@link LockInfo#from} method. *

    - * If cd does not contain this attribute, + * If {@code cd} does not contain this attribute, * this attribute will be set to an empty array.

    daemon{@code java.lang.Boolean}
    priority{@code java.lang.Integer}
    *
    * - * @param cd CompositeData representing a ThreadInfo + * @param cd {@code CompositeData} representing a {@code ThreadInfo} * - * @throws IllegalArgumentException if cd does not - * represent a ThreadInfo with the attributes described + * @throws IllegalArgumentException if {@code cd} does not + * represent a {@code ThreadInfo} with the attributes described * above. * - * @return a ThreadInfo object represented - * by cd if cd is not null; - * null otherwise. + * @return a {@code ThreadInfo} object represented + * by {@code cd} if {@code cd} is not {@code null}; + * {@code null} otherwise. */ public static ThreadInfo from(CompositeData cd) { if (cd == null) { @@ -798,12 +849,12 @@ public class ThreadInfo { /** * Returns an array of {@link MonitorInfo} objects, each of which * represents an object monitor currently locked by the thread - * associated with this ThreadInfo. + * associated with this {@code ThreadInfo}. * If no locked monitor was requested for this thread info or * no monitor is locked by the thread, this method * will return a zero-length array. * - * @return an array of MonitorInfo objects representing + * @return an array of {@code MonitorInfo} objects representing * the object monitors locked by the thread. * * @since 1.6 @@ -816,11 +867,11 @@ public class ThreadInfo { * Returns an array of {@link LockInfo} objects, each of which * represents an ownable * synchronizer currently locked by the thread associated with - * this ThreadInfo. If no locked synchronizer was + * this {@code ThreadInfo}. If no locked synchronizer was * requested for this thread info or no synchronizer is locked by * the thread, this method will return a zero-length array. * - * @return an array of LockInfo objects representing + * @return an array of {@code LockInfo} objects representing * the ownable synchronizers locked by the thread. * * @since 1.6 diff --git a/jdk/src/java.management/share/classes/sun/management/ThreadInfoCompositeData.java b/jdk/src/java.management/share/classes/sun/management/ThreadInfoCompositeData.java index 1067c175939..e2d0357300f 100644 --- a/jdk/src/java.management/share/classes/sun/management/ThreadInfoCompositeData.java +++ b/jdk/src/java.management/share/classes/sun/management/ThreadInfoCompositeData.java @@ -43,23 +43,30 @@ public class ThreadInfoCompositeData extends LazyCompositeData { private final ThreadInfo threadInfo; private final CompositeData cdata; private final boolean currentVersion; + private final boolean hasV6; private ThreadInfoCompositeData(ThreadInfo ti) { this.threadInfo = ti; this.currentVersion = true; this.cdata = null; + this.hasV6 = true; } private ThreadInfoCompositeData(CompositeData cd) { this.threadInfo = null; this.currentVersion = ThreadInfoCompositeData.isCurrentVersion(cd); this.cdata = cd; + this.hasV6 = ThreadInfoCompositeData.hasV6(cd); } public ThreadInfo getThreadInfo() { return threadInfo; } + public boolean hasV6() { + return hasV6; + } + public boolean isCurrentVersion() { return currentVersion; } @@ -124,6 +131,8 @@ public class ThreadInfoCompositeData extends LazyCompositeData { threadInfo.isInNative(), lockedMonitorsData, lockedSyncsData, + threadInfo.isDaemon(), + threadInfo.getPriority(), }; try { @@ -151,6 +160,8 @@ public class ThreadInfoCompositeData extends LazyCompositeData { private static final String STACK_TRACE = "stackTrace"; private static final String SUSPENDED = "suspended"; private static final String IN_NATIVE = "inNative"; + private static final String DAEMON = "daemon"; + private static final String PRIORITY = "priority"; private static final String LOCKED_MONITORS = "lockedMonitors"; private static final String LOCKED_SYNCS = "lockedSynchronizers"; @@ -171,6 +182,8 @@ public class ThreadInfoCompositeData extends LazyCompositeData { IN_NATIVE, LOCKED_MONITORS, LOCKED_SYNCS, + DAEMON, + PRIORITY, }; // New attributes added in 6.0 ThreadInfo @@ -180,9 +193,16 @@ public class ThreadInfoCompositeData extends LazyCompositeData { LOCKED_SYNCS, }; + private static final String[] threadInfoV9Attributes = { + DAEMON, + PRIORITY, + }; + // Current version of ThreadInfo private static final CompositeType threadInfoCompositeType; // Previous version of ThreadInfo + private static final CompositeType threadInfoV6CompositeType; + // Previous-previous version of ThreadInfo private static final CompositeType threadInfoV5CompositeType; private static final CompositeType lockInfoCompositeType; static { @@ -193,7 +213,7 @@ public class ThreadInfoCompositeData extends LazyCompositeData { String[] itemNames = threadInfoCompositeType.keySet().toArray(new String[0]); int numV5Attributes = threadInfoItemNames.length - - threadInfoV6Attributes.length; + threadInfoV6Attributes.length - threadInfoV9Attributes.length; String[] v5ItemNames = new String[numV5Attributes]; String[] v5ItemDescs = new String[numV5Attributes]; OpenType[] v5ItemTypes = new OpenType[numV5Attributes]; @@ -213,6 +233,31 @@ public class ThreadInfoCompositeData extends LazyCompositeData { v5ItemNames, v5ItemDescs, v5ItemTypes); + + + // Form a CompositeType for JDK 6.0 ThreadInfo version + int numV6Attributes = threadInfoItemNames.length - + threadInfoV9Attributes.length; + String[] v6ItemNames = new String[numV6Attributes]; + String[] v6ItemDescs = new String[numV6Attributes]; + OpenType[] v6ItemTypes = new OpenType[numV6Attributes]; + i = 0; + for (String n : itemNames) { + if (isV5Attribute(n) || isV6Attribute(n)) { + v6ItemNames[i] = n; + v6ItemDescs[i] = threadInfoCompositeType.getDescription(n); + v6ItemTypes[i] = threadInfoCompositeType.getType(n); + i++; + } + } + + threadInfoV6CompositeType = + new CompositeType("java.lang.management.ThreadInfo", + "Java SE 6 java.lang.management.ThreadInfo", + v6ItemNames, + v6ItemDescs, + v6ItemTypes); + } catch (OpenDataException e) { // Should never reach here throw new AssertionError(e); @@ -236,6 +281,20 @@ public class ThreadInfoCompositeData extends LazyCompositeData { return false; } } + for (String n : threadInfoV9Attributes) { + if (itemName.equals(n)) { + return false; + } + } + return true; + } + + private static boolean isV6Attribute(String itemName) { + for (String n : threadInfoV9Attributes) { + if (itemName.equals(n)) { + return false; + } + } return true; } @@ -247,6 +306,15 @@ public class ThreadInfoCompositeData extends LazyCompositeData { return isTypeMatched(threadInfoCompositeType, cd.getCompositeType()); } + private static boolean hasV6(CompositeData cd) { + if (cd == null) { + throw new NullPointerException("Null CompositeData"); + } + + return isTypeMatched(threadInfoCompositeType, cd.getCompositeType()) || + isTypeMatched(threadInfoV6CompositeType, cd.getCompositeType()); + } + public long threadId() { return getLong(cdata, THREAD_ID); } @@ -304,6 +372,14 @@ public class ThreadInfoCompositeData extends LazyCompositeData { return getBoolean(cdata, IN_NATIVE); } + public boolean isDaemon() { + return getBoolean(cdata, DAEMON); + } + + public int getPriority(){ + return getInt(cdata, PRIORITY); + } + public StackTraceElement[] stackTrace() { CompositeData[] stackTraceData = (CompositeData[]) cdata.get(STACK_TRACE); @@ -368,9 +444,10 @@ public class ThreadInfoCompositeData extends LazyCompositeData { if (!isTypeMatched(threadInfoCompositeType, type)) { currentVersion = false; // check if cd is an older version - if (!isTypeMatched(threadInfoV5CompositeType, type)) { - throw new IllegalArgumentException( - "Unexpected composite type for ThreadInfo"); + if (!isTypeMatched(threadInfoV5CompositeType, type) && + !isTypeMatched(threadInfoV6CompositeType, type)) { + throw new IllegalArgumentException( + "Unexpected composite type for ThreadInfo"); } } diff --git a/jdk/test/java/lang/management/CompositeData/ThreadInfoCompositeData.java b/jdk/test/java/lang/management/CompositeData/ThreadInfoCompositeData.java index 9646b61fb15..5dc809ac04a 100644 --- a/jdk/test/java/lang/management/CompositeData/ThreadInfoCompositeData.java +++ b/jdk/test/java/lang/management/CompositeData/ThreadInfoCompositeData.java @@ -147,6 +147,11 @@ public class ThreadInfoCompositeData { info.getLockOwnerName() + " expected = " + values[LOCK_OWNER_NAME]); } + if (!values[DAEMON].equals(info.isDaemon())) { + throw new RuntimeException("Daemon = " + + info.isDaemon() + " expected = " + + values[DAEMON]); + } checkStackTrace(info.getStackTrace()); @@ -258,8 +263,11 @@ public class ThreadInfoCompositeData { private static final int SUSPENDED = 11; private static final int IN_NATIVE = 12; private static final int NUM_V5_ATTS = 13; - // JDK 6.0 ThreadInfo attribtues + // JDK 6.0 ThreadInfo attributes private static final int LOCK_INFO = 13; + // JDK 9.0 ThreadInfo attributes + private static final int DAEMON = 14; + private static final int PRIORITY = 15; private static final String[] validItemNames = { "threadId", @@ -276,6 +284,8 @@ public class ThreadInfoCompositeData { "suspended", "inNative", "lockInfo", + "daemon", + "priority", }; private static OpenType[] validItemTypes = { @@ -293,6 +303,8 @@ public class ThreadInfoCompositeData { SimpleType.BOOLEAN, SimpleType.BOOLEAN, null, // CompositeType for LockInfo + SimpleType.BOOLEAN, + SimpleType.INTEGER, }; private static Object[] values = { @@ -310,6 +322,8 @@ public class ThreadInfoCompositeData { new Boolean(false), new Boolean(false), null, // To be initialized to lockInfoCD + new Boolean(false), + Thread.NORM_PRIORITY, }; private static final String[] steItemNames = { @@ -381,6 +395,8 @@ public class ThreadInfoCompositeData { "suspended", "inNative", "lockInfo", + "daemon", + "priority", }; private static final OpenType[] badItemTypes = { SimpleType.LONG, @@ -397,6 +413,8 @@ public class ThreadInfoCompositeData { SimpleType.BOOLEAN, SimpleType.BOOLEAN, SimpleType.LONG, // bad type + SimpleType.BOOLEAN, + SimpleType.INTEGER, }; } diff --git a/jdk/test/java/lang/management/ThreadMXBean/ThreadDaemonTest.java b/jdk/test/java/lang/management/ThreadMXBean/ThreadDaemonTest.java new file mode 100644 index 00000000000..35cad89268b --- /dev/null +++ b/jdk/test/java/lang/management/ThreadMXBean/ThreadDaemonTest.java @@ -0,0 +1,96 @@ +/* + * 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.lang.management.*; +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; + +/* + * @test + * @bug 6588467 + * @summary Basic test of ThreadInfo.isDaemon + * @author Jeremy Manson + */ +public class ThreadDaemonTest { + + public static void main(String[] args) throws Exception { + final int NUM_THREADS = 20; + final String THREAD_PREFIX = "ThreadDaemonTest-"; + + final CountDownLatch started = new CountDownLatch(NUM_THREADS); + final CountDownLatch finished = new CountDownLatch(1); + final AtomicReference fail = new AtomicReference<>(null); + + Thread[] allThreads = new Thread[NUM_THREADS]; + ThreadMXBean mbean = ManagementFactory.getThreadMXBean(); + Random rand = new Random(); + + for (int i = 0; i < NUM_THREADS; i++) { + allThreads[i] = new Thread(new Runnable() { + public void run() { + try { + started.countDown(); + finished.await(); + } catch (InterruptedException e) { + fail.set(new Exception( + "Unexpected InterruptedException")); + } + } + }, THREAD_PREFIX + i); + allThreads[i].setDaemon(rand.nextBoolean()); + allThreads[i].start(); + } + + started.await(); + try { + ThreadInfo[] allThreadInfos = mbean.dumpAllThreads(false, false); + int count = 0; + for (int i = 0; i < allThreadInfos.length; i++) { + String threadName = allThreadInfos[i].getThreadName(); + if (threadName.startsWith(THREAD_PREFIX)) { + count++; + String[] nameAndNumber = threadName.split("-"); + int threadNum = Integer.parseInt(nameAndNumber[1]); + if (allThreads[threadNum].isDaemon() != + allThreadInfos[i].isDaemon()) { + throw new RuntimeException( + allThreads[threadNum] + " is not like " + + allThreadInfos[i] + ". TEST FAILED."); + } + } + } + if (count != NUM_THREADS) { + throw new RuntimeException("Wrong number of threads examined"); + } + } + finally { finished.countDown(); } + + for (int i = 0; i < NUM_THREADS; i++) { + allThreads[i].join(); + } + if (fail.get() != null) { + throw fail.get(); + } + } +} diff --git a/jdk/test/java/lang/management/ThreadMXBean/ThreadDump.java b/jdk/test/java/lang/management/ThreadMXBean/ThreadDump.java index 5ba005e60c7..709b7ecfe8c 100644 --- a/jdk/test/java/lang/management/ThreadMXBean/ThreadDump.java +++ b/jdk/test/java/lang/management/ThreadMXBean/ThreadDump.java @@ -34,6 +34,7 @@ public class ThreadDump { public static void printThreadInfo(ThreadInfo ti) { StringBuilder sb = new StringBuilder("\"" + ti.getThreadName() + "\"" + + (ti.isDaemon() ? " daemon" : "") + " Id=" + ti.getThreadId() + " in " + ti.getThreadState()); if (ti.getLockName() != null) { From 93d09edf065334549f1f2b1b8065be4ceb95fa12 Mon Sep 17 00:00:00 2001 From: Staffan Larsen Date: Tue, 24 Feb 2015 10:56:48 +0100 Subject: [PATCH 10/29] 8073713: javadoc warnings in serviceability code Reviewed-by: mgronlun, alanb, sspitsyn --- .../classes/com/sun/management/HotSpotDiagnosticMXBean.java | 2 +- .../com/sun/tools/attach/AttachOperationFailedException.java | 2 +- jdk/src/jdk.jdi/share/classes/com/sun/jdi/InterfaceType.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jdk/src/java.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java b/jdk/src/java.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java index c95ac52b68d..0fd641e0612 100644 --- a/jdk/src/java.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java +++ b/jdk/src/java.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java @@ -45,7 +45,7 @@ import java.lang.management.PlatformManagedObject; * All methods throw a {@code NullPointerException} if any input argument is * {@code null} unless it's stated otherwise. * - * @see ManagementFactory#getPlatformMXBeans(Class) + * @see java.lang.management.ManagementFactory#getPlatformMXBeans(Class) */ @jdk.Exported public interface HotSpotDiagnosticMXBean extends PlatformManagedObject { diff --git a/jdk/src/jdk.attach/share/classes/com/sun/tools/attach/AttachOperationFailedException.java b/jdk/src/jdk.attach/share/classes/com/sun/tools/attach/AttachOperationFailedException.java index 7f676ee4993..fd37bb3f732 100644 --- a/jdk/src/jdk.attach/share/classes/com/sun/tools/attach/AttachOperationFailedException.java +++ b/jdk/src/jdk.attach/share/classes/com/sun/tools/attach/AttachOperationFailedException.java @@ -46,7 +46,7 @@ public class AttachOperationFailedException extends IOException { * Constructs an AttachOperationFailedException with * the specified detail message. * - * @param s the detail message. + * @param message the detail message. */ public AttachOperationFailedException(String message) { super(message); diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/InterfaceType.java b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/InterfaceType.java index 9436e487387..80250de8a5d 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/InterfaceType.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/InterfaceType.java @@ -145,7 +145,7 @@ public interface InterfaceType extends ReferenceType { * not be done from the client's event handler thread. *

    * The resumption of other threads during the invocation can be prevented - * by specifying the {@link #INVOKE_SINGLE_THREADED} + * by specifying the {@link ClassType#INVOKE_SINGLE_THREADED} * bit flag in the options argument; however, * there is no protection against or recovery from the deadlocks * described above, so this option should be used with great caution. From f3c492437958a26dde4fab9d9da51f25ac97d834 Mon Sep 17 00:00:00 2001 From: Ivan Gerasimov Date: Tue, 24 Feb 2015 19:50:17 +0300 Subject: [PATCH 11/29] 8073779: StackOverflowError called StackOverflowException in javadoc Reviewed-by: martin --- .../java.base/share/classes/java/util/stream/DoubleStream.java | 2 +- jdk/src/java.base/share/classes/java/util/stream/IntStream.java | 2 +- .../java.base/share/classes/java/util/stream/LongStream.java | 2 +- jdk/src/java.base/share/classes/java/util/stream/Stream.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/util/stream/DoubleStream.java b/jdk/src/java.base/share/classes/java/util/stream/DoubleStream.java index 08b4eeda304..be6cc98aa60 100644 --- a/jdk/src/java.base/share/classes/java/util/stream/DoubleStream.java +++ b/jdk/src/java.base/share/classes/java/util/stream/DoubleStream.java @@ -848,7 +848,7 @@ public interface DoubleStream extends BaseStream { * @implNote * Use caution when constructing streams from repeated concatenation. * Accessing an element of a deeply concatenated stream can result in deep - * call chains, or even {@code StackOverflowException}. + * call chains, or even {@code StackOverflowError}. * * @param a the first stream * @param b the second stream diff --git a/jdk/src/java.base/share/classes/java/util/stream/IntStream.java b/jdk/src/java.base/share/classes/java/util/stream/IntStream.java index 0a67d5a19dd..b68084b5d40 100644 --- a/jdk/src/java.base/share/classes/java/util/stream/IntStream.java +++ b/jdk/src/java.base/share/classes/java/util/stream/IntStream.java @@ -837,7 +837,7 @@ public interface IntStream extends BaseStream { * @implNote * Use caution when constructing streams from repeated concatenation. * Accessing an element of a deeply concatenated stream can result in deep - * call chains, or even {@code StackOverflowException}. + * call chains, or even {@code StackOverflowError}. * * @param a the first stream * @param b the second stream diff --git a/jdk/src/java.base/share/classes/java/util/stream/LongStream.java b/jdk/src/java.base/share/classes/java/util/stream/LongStream.java index 78901b2b1c2..14d6d0b5eb9 100644 --- a/jdk/src/java.base/share/classes/java/util/stream/LongStream.java +++ b/jdk/src/java.base/share/classes/java/util/stream/LongStream.java @@ -845,7 +845,7 @@ public interface LongStream extends BaseStream { * @implNote * Use caution when constructing streams from repeated concatenation. * Accessing an element of a deeply concatenated stream can result in deep - * call chains, or even {@code StackOverflowException}. + * call chains, or even {@code StackOverflowError}. * * @param a the first stream * @param b the second stream diff --git a/jdk/src/java.base/share/classes/java/util/stream/Stream.java b/jdk/src/java.base/share/classes/java/util/stream/Stream.java index 0070658b01f..8c48bcb1a13 100644 --- a/jdk/src/java.base/share/classes/java/util/stream/Stream.java +++ b/jdk/src/java.base/share/classes/java/util/stream/Stream.java @@ -1079,7 +1079,7 @@ public interface Stream extends BaseStream> { * @implNote * Use caution when constructing streams from repeated concatenation. * Accessing an element of a deeply concatenated stream can result in deep - * call chains, or even {@code StackOverflowException}. + * call chains, or even {@code StackOverflowError}. * * @param The type of stream elements * @param a the first stream From 2390a77789570a2767ebca21da7c2a5675cff76f Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Tue, 24 Feb 2015 21:51:45 +0100 Subject: [PATCH 12/29] 8073394: Clock.systemUTC() should return a constant Clock.systemUTC() now returns SystemClock.UTC Reviewed-by: scolebourne, rriggs, plevart, lancea --- .../share/classes/java/time/Clock.java | 7 ++++- .../time/test/java/time/TestClock_System.java | 29 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/jdk/src/java.base/share/classes/java/time/Clock.java b/jdk/src/java.base/share/classes/java/time/Clock.java index 28dd55f9b8d..6402806070d 100644 --- a/jdk/src/java.base/share/classes/java/time/Clock.java +++ b/jdk/src/java.base/share/classes/java/time/Clock.java @@ -155,7 +155,7 @@ public abstract class Clock { * @return a clock that uses the best available system clock in the UTC zone, not null */ public static Clock systemUTC() { - return new SystemClock(ZoneOffset.UTC); + return SystemClock.UTC; } /** @@ -198,6 +198,9 @@ public abstract class Clock { */ public static Clock system(ZoneId zone) { Objects.requireNonNull(zone, "zone"); + if (zone == ZoneOffset.UTC) { + return SystemClock.UTC; + } return new SystemClock(zone); } @@ -451,6 +454,8 @@ public abstract class Clock { private static final long serialVersionUID = 6740630888130243051L; private static final long OFFSET_SEED = System.currentTimeMillis()/1000 - 1024; // initial offest + static final SystemClock UTC = new SystemClock(ZoneOffset.UTC); + private final ZoneId zone; // We don't actually need a volatile here. // We don't care if offset is set or read concurrently by multiple diff --git a/jdk/test/java/time/test/java/time/TestClock_System.java b/jdk/test/java/time/test/java/time/TestClock_System.java index 527008920cc..b311dad6e6c 100644 --- a/jdk/test/java/time/test/java/time/TestClock_System.java +++ b/jdk/test/java/time/test/java/time/TestClock_System.java @@ -66,8 +66,10 @@ import java.lang.reflect.Field; import java.time.Clock; import java.time.Instant; import java.time.ZoneId; +import java.time.ZoneOffset; import org.testng.annotations.Test; +import org.testng.annotations.DataProvider; /** * Test system clock. @@ -76,6 +78,7 @@ import org.testng.annotations.Test; public class TestClock_System { private static final ZoneId PARIS = ZoneId.of("Europe/Paris"); + private static final Clock systemUTC = Clock.systemUTC(); public void test_withZone_same() { Clock test = Clock.system(PARIS); @@ -89,6 +92,32 @@ public class TestClock_System { assertEquals(test.toString(), "SystemClock[Europe/Paris]"); } + //----------------------------------------------------------------------- + @DataProvider(name="sampleSystemUTC") + Object[][] provider_sampleSystemUTC() { + return new Object[][] { + {"Clock.systemUTC()#1", Clock.systemUTC()}, + {"Clock.systemUTC()#2", Clock.systemUTC()}, + {"Clock.system(ZoneOffset.UTC)#1", Clock.system(ZoneOffset.UTC)}, + {"Clock.system(ZoneOffset.UTC)#2", Clock.system(ZoneOffset.UTC)} + }; + } + + // Test for 8073394 + @Test(dataProvider="sampleSystemUTC") + public void test_systemUTC(String s, Clock clock) { + if (clock != systemUTC) { + throw new RuntimeException("Unexpected clock instance for " + s + ": " + + "\n\texpected: " + toString(systemUTC) + + "\n\tactual: " + toString(clock)); + } + } + + private static String toString(Clock c) { + return c == null ? null : + c + " " + c.getClass().getName() + "@" + System.identityHashCode(c); + } + //----------------------------------------------------------------------- private static String formatTime(String prefix, Instant time) { From f2313d073e5c7f1f82bb03c0c05c9ff4d1b5fdb1 Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Tue, 24 Feb 2015 12:45:56 -0800 Subject: [PATCH 13/29] 8073696: Remove unused imports in java.corba, java.jaxws, jdk.httpserver Reviewed-by: alanb, chegar --- .../share/classes/com/sun/net/httpserver/HttpExchange.java | 1 - .../share/classes/sun/net/httpserver/AuthFilter.java | 1 - .../share/classes/sun/net/httpserver/HttpExchangeImpl.java | 1 - .../share/classes/sun/net/httpserver/HttpsExchangeImpl.java | 1 - 4 files changed, 4 deletions(-) diff --git a/jdk/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpExchange.java b/jdk/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpExchange.java index 5a9c4d925de..73d7a0e5f5c 100644 --- a/jdk/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpExchange.java +++ b/jdk/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpExchange.java @@ -31,7 +31,6 @@ import java.nio.channels.*; import java.net.*; import javax.net.ssl.*; import java.util.*; -import sun.net.www.MessageHeader; /** * This class encapsulates a HTTP request received and a diff --git a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/AuthFilter.java b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/AuthFilter.java index 5b2708335c2..d56ae8aa94d 100644 --- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/AuthFilter.java +++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/AuthFilter.java @@ -29,7 +29,6 @@ import com.sun.net.httpserver.*; import java.io.*; import java.nio.*; import java.nio.channels.*; -import sun.net.www.MessageHeader; import java.util.*; import javax.security.auth.*; import javax.security.auth.callback.*; diff --git a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/HttpExchangeImpl.java b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/HttpExchangeImpl.java index daeaea899b0..420ef3d9e64 100644 --- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/HttpExchangeImpl.java +++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/HttpExchangeImpl.java @@ -31,7 +31,6 @@ import java.nio.channels.*; import java.net.*; import javax.net.ssl.*; import java.util.*; -import sun.net.www.MessageHeader; import com.sun.net.httpserver.*; import com.sun.net.httpserver.spi.*; diff --git a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/HttpsExchangeImpl.java b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/HttpsExchangeImpl.java index 7b38de53ce9..f7f43d7feca 100644 --- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/HttpsExchangeImpl.java +++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/HttpsExchangeImpl.java @@ -31,7 +31,6 @@ import java.nio.channels.*; import java.net.*; import javax.net.ssl.*; import java.util.*; -import sun.net.www.MessageHeader; import com.sun.net.httpserver.*; import com.sun.net.httpserver.spi.*; From ed25ae3aeb7ded2931b9292b100e966d04766c2c Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 25 Feb 2015 18:30:07 +0800 Subject: [PATCH 14/29] 8073181: keytool -ext honored not working correctly Reviewed-by: mullan --- .../share/classes/sun/security/tools/keytool/Main.java | 9 ++++++--- jdk/test/sun/security/tools/keytool/KeyToolTest.java | 10 ++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java index 2a0bcb1916a..1aee1649946 100644 --- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java +++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java @@ -3806,14 +3806,15 @@ public final class Main { if (item.equals("all")) continue; // add or remove - boolean add = true; - // -1, unchanged, 0 crtical, 1 non-critical + boolean add; + // -1, unchanged, 0 critical, 1 non-critical int action = -1; String type = null; if (item.startsWith("-")) { add = false; type = item.substring(1); } else { + add = true; int colonpos = item.indexOf(':'); if (colonpos >= 0) { type = item.substring(0, colonpos); @@ -3823,6 +3824,8 @@ public final class Main { throw new Exception(rb.getString ("Illegal.value.") + item); } + } else { + type = item; } } String n = reqex.getNameByOid(findOidForExtName(type)); @@ -3834,8 +3837,8 @@ public final class Main { e.getExtensionId(), !e.isCritical(), e.getExtensionValue()); - ext.set(n, e); } + ext.set(n, e); } else { ext.delete(n); } diff --git a/jdk/test/sun/security/tools/keytool/KeyToolTest.java b/jdk/test/sun/security/tools/keytool/KeyToolTest.java index 3036af8be7a..6658e20c3e5 100644 --- a/jdk/test/sun/security/tools/keytool/KeyToolTest.java +++ b/jdk/test/sun/security/tools/keytool/KeyToolTest.java @@ -1184,6 +1184,16 @@ public class KeyToolTest { assertTrue(!a.getExtension(new ObjectIdentifier("2.3.4")).isCritical()); assertTrue(a.getExtensionValue("2.3.4").length == 6); + // 8073181: keytool -ext honored not working correctly + testOK("", simple+"-gencert -alias ca -infile test.req -ext " + + "honored=1.2.3,1.2.4:critical " + + "-debug -rfc -outfile test2.cert"); + testOK("", simple+"-importcert -file test2.cert -alias b"); + ks = loadStore("x.jks", "changeit", "JKS"); + X509CertImpl b = (X509CertImpl)ks.getCertificate("b"); + assertTrue(!b.getExtension(new ObjectIdentifier("1.2.3")).isCritical()); + assertTrue(b.getExtension(new ObjectIdentifier("1.2.4")).isCritical()); + remove("x.jks"); remove("test.req"); remove("test.cert"); From b505d5ad0562e31a415c7df39bfbcab5c0628806 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 25 Feb 2015 18:30:29 +0800 Subject: [PATCH 15/29] 8073182: keytool may generate duplicate extensions Reviewed-by: mullan --- .../sun/security/tools/keytool/Main.java | 83 ++++++++++--------- .../security/tools/keytool/KeyToolTest.java | 6 ++ 2 files changed, 50 insertions(+), 39 deletions(-) diff --git a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java index 1aee1649946..63839b95df0 100644 --- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java +++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java @@ -3765,41 +3765,55 @@ public final class Main { } } + // Add an extension into a CertificateExtensions, always using OID as key + private static void setExt(CertificateExtensions result, Extension ex) + throws IOException { + result.set(ex.getId(), ex); + } + /** * Create X509v3 extensions from a string representation. Note that the * SubjectKeyIdentifierExtension will always be created non-critical besides * the extension requested in the extstr argument. * - * @param reqex the requested extensions, can be null, used for -gencert - * @param ext the original extensions, can be null, used for -selfcert + * @param requestedEx the requested extensions, can be null, used for -gencert + * @param existingEx the original extensions, can be null, used for -selfcert * @param extstrs -ext values, Read keytool doc * @param pkey the public key for the certificate * @param akey the public key for the authority (issuer) * @return the created CertificateExtensions */ private CertificateExtensions createV3Extensions( - CertificateExtensions reqex, - CertificateExtensions ext, + CertificateExtensions requestedEx, + CertificateExtensions existingEx, List extstrs, PublicKey pkey, PublicKey akey) throws Exception { - if (ext != null && reqex != null) { + if (existingEx != null && requestedEx != null) { // This should not happen throw new Exception("One of request and original should be null."); } - if (ext == null) ext = new CertificateExtensions(); + // A new extensions always using OID as key + CertificateExtensions result = new CertificateExtensions(); + if (existingEx != null) { + for (Extension ex: existingEx.getAllExtensions()) { + setExt(result, ex); + } + } try { // name{:critical}{=value} // Honoring requested extensions - if (reqex != null) { + if (requestedEx != null) { for(String extstr: extstrs) { if (extstr.toLowerCase(Locale.ENGLISH).startsWith("honored=")) { List list = Arrays.asList( extstr.toLowerCase(Locale.ENGLISH).substring(8).split(",")); // First check existence of "all" if (list.contains("all")) { - ext = reqex; // we know ext was null + for (Extension ex: requestedEx.getAllExtensions()) { + setExt(result, ex); + } } // one by one for others for (String item: list) { @@ -3828,9 +3842,9 @@ public final class Main { type = item; } } - String n = reqex.getNameByOid(findOidForExtName(type)); + String n = findOidForExtName(type).toString(); if (add) { - Extension e = reqex.get(n); + Extension e = requestedEx.get(n); if (!e.isCritical() && action == 0 || e.isCritical() && action == 1) { e = Extension.newExtension( @@ -3838,9 +3852,9 @@ public final class Main { !e.isCritical(), e.getExtensionValue()); } - ext.set(n, e); + setExt(result, e); } else { - ext.delete(n); + result.delete(n); } } break; @@ -3902,8 +3916,7 @@ public final class Main { } } } - ext.set(BasicConstraintsExtension.NAME, - new BasicConstraintsExtension(isCritical, isCA, + setExt(result, new BasicConstraintsExtension(isCritical, isCA, pathLen)); break; case 1: // KU @@ -3931,7 +3944,7 @@ public final class Main { KeyUsageExtension kue = new KeyUsageExtension(ok); // The above KeyUsageExtension constructor does not // allow isCritical value, so... - ext.set(KeyUsageExtension.NAME, Extension.newExtension( + setExt(result, Extension.newExtension( kue.getExtensionId(), isCritical, kue.getExtensionValue())); @@ -3969,8 +3982,7 @@ public final class Main { v.add(new ObjectIdentifier("1.3.6.1.5.5.7.3." + p)); } } - ext.set(ExtendedKeyUsageExtension.NAME, - new ExtendedKeyUsageExtension(isCritical, v)); + setExt(result, new ExtendedKeyUsageExtension(isCritical, v)); } else { throw new Exception(rb.getString ("Illegal.value.") + extstr); @@ -3991,13 +4003,11 @@ public final class Main { gnames.add(createGeneralName(t, v)); } if (exttype == 3) { - ext.set(SubjectAlternativeNameExtension.NAME, - new SubjectAlternativeNameExtension( - isCritical, gnames)); + setExt(result, new SubjectAlternativeNameExtension( + isCritical, gnames)); } else { - ext.set(IssuerAlternativeNameExtension.NAME, - new IssuerAlternativeNameExtension( - isCritical, gnames)); + setExt(result, new IssuerAlternativeNameExtension( + isCritical, gnames)); } } else { throw new Exception(rb.getString @@ -4047,11 +4057,9 @@ public final class Main { oid, createGeneralName(t, v))); } if (exttype == 5) { - ext.set(SubjectInfoAccessExtension.NAME, - new SubjectInfoAccessExtension(accessDescriptions)); + setExt(result, new SubjectInfoAccessExtension(accessDescriptions)); } else { - ext.set(AuthorityInfoAccessExtension.NAME, - new AuthorityInfoAccessExtension(accessDescriptions)); + setExt(result, new AuthorityInfoAccessExtension(accessDescriptions)); } } else { throw new Exception(rb.getString @@ -4071,10 +4079,9 @@ public final class Main { String v = item.substring(colonpos+1); gnames.add(createGeneralName(t, v)); } - ext.set(CRLDistributionPointsExtension.NAME, - new CRLDistributionPointsExtension( - isCritical, Collections.singletonList( - new DistributionPoint(gnames, null, null)))); + setExt(result, new CRLDistributionPointsExtension( + isCritical, Collections.singletonList( + new DistributionPoint(gnames, null, null)))); } else { throw new Exception(rb.getString ("Illegal.value.") + extstr); @@ -4112,7 +4119,7 @@ public final class Main { } else { data = new byte[0]; } - ext.set(oid.toString(), new Extension(oid, isCritical, + setExt(result, new Extension(oid, isCritical, new DerValue(DerValue.tag_OctetString, data) .toByteArray())); break; @@ -4122,18 +4129,16 @@ public final class Main { } } // always non-critical - ext.set(SubjectKeyIdentifierExtension.NAME, - new SubjectKeyIdentifierExtension( - new KeyIdentifier(pkey).getIdentifier())); + setExt(result, new SubjectKeyIdentifierExtension( + new KeyIdentifier(pkey).getIdentifier())); if (akey != null && !pkey.equals(akey)) { - ext.set(AuthorityKeyIdentifierExtension.NAME, - new AuthorityKeyIdentifierExtension( - new KeyIdentifier(akey), null, null)); + setExt(result, new AuthorityKeyIdentifierExtension( + new KeyIdentifier(akey), null, null)); } } catch(IOException e) { throw new RuntimeException(e); } - return ext; + return result; } /** diff --git a/jdk/test/sun/security/tools/keytool/KeyToolTest.java b/jdk/test/sun/security/tools/keytool/KeyToolTest.java index 6658e20c3e5..bedf9824c91 100644 --- a/jdk/test/sun/security/tools/keytool/KeyToolTest.java +++ b/jdk/test/sun/security/tools/keytool/KeyToolTest.java @@ -1194,6 +1194,12 @@ public class KeyToolTest { assertTrue(!b.getExtension(new ObjectIdentifier("1.2.3")).isCritical()); assertTrue(b.getExtension(new ObjectIdentifier("1.2.4")).isCritical()); + // 8073182: keytool may generate duplicate extensions + testOK("", pre+"dup -ext bc=2 -ext 2.5.29.19=30030101FF -ext bc=3"); + ks = loadStore("x.jks", "changeit", "JKS"); + X509CertImpl dup = (X509CertImpl)ks.getCertificate("dup"); + assertTrue(dup.getBasicConstraints() == 3); + remove("x.jks"); remove("test.req"); remove("test.cert"); From 6d78b91ac967f2e19850e8ffb6c1faa7389896a4 Mon Sep 17 00:00:00 2001 From: Sean Coffey Date: Wed, 25 Feb 2015 11:44:53 +0000 Subject: [PATCH 16/29] 7178362: Socket impls should ignore unsupported proxy types rather than throwing Reviewed-by: chegar --- .../classes/java/net/SocksSocketImpl.java | 14 ++- jdk/test/java/net/Socks/BadProxySelector.java | 85 +++++++++++++++++++ 2 files changed, 91 insertions(+), 8 deletions(-) create mode 100644 jdk/test/java/net/Socks/BadProxySelector.java diff --git a/jdk/src/java.base/share/classes/java/net/SocksSocketImpl.java b/jdk/src/java.base/share/classes/java/net/SocksSocketImpl.java index 7c0f899b8e6..3dd4259cd9a 100644 --- a/jdk/src/java.base/share/classes/java/net/SocksSocketImpl.java +++ b/jdk/src/java.base/share/classes/java/net/SocksSocketImpl.java @@ -388,14 +388,13 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { } while (iProxy.hasNext()) { p = iProxy.next(); - if (p == null || p == Proxy.NO_PROXY) { + if (p == null || p.type() != Proxy.Type.SOCKS) { super.connect(epoint, remainingMillis(deadlineMillis)); return; } - if (p.type() != Proxy.Type.SOCKS) - throw new SocketException("Unknown proxy type : " + p.type()); + if (!(p.address() instanceof InetSocketAddress)) - throw new SocketException("Unknow address type for proxy: " + p); + throw new SocketException("Unknown address type for proxy: " + p); // Use getHostString() to avoid reverse lookups server = ((InetSocketAddress) p.address()).getHostString(); serverPort = ((InetSocketAddress) p.address()).getPort(); @@ -707,13 +706,12 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { } while (iProxy.hasNext()) { p = iProxy.next(); - if (p == null || p == Proxy.NO_PROXY) { + if (p == null || p.type() != Proxy.Type.SOCKS) { return; } - if (p.type() != Proxy.Type.SOCKS) - throw new SocketException("Unknown proxy type : " + p.type()); + if (!(p.address() instanceof InetSocketAddress)) - throw new SocketException("Unknow address type for proxy: " + p); + throw new SocketException("Unknown address type for proxy: " + p); // Use getHostString() to avoid reverse lookups server = ((InetSocketAddress) p.address()).getHostString(); serverPort = ((InetSocketAddress) p.address()).getPort(); diff --git a/jdk/test/java/net/Socks/BadProxySelector.java b/jdk/test/java/net/Socks/BadProxySelector.java new file mode 100644 index 00000000000..008e9fc4b00 --- /dev/null +++ b/jdk/test/java/net/Socks/BadProxySelector.java @@ -0,0 +1,85 @@ +/* + * 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 7178362 + * @run main/othervm BadProxySelector + */ + +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.ProxySelector; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.ServerSocket; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.io.*; + +public class BadProxySelector { + public static void main(String[] args) throws Exception { + ProxySelector.setDefault(new HTTPProxySelector()); + try (ServerSocket ss = new ServerSocket(0); + Socket s1 = new Socket(ss.getInetAddress(), ss.getLocalPort()); + Socket s2 = ss.accept()) { + } + + ProxySelector.setDefault(new NullHTTPProxySelector()); + try (ServerSocket ss = new ServerSocket(0); + Socket s1 = new Socket(ss.getInetAddress(), ss.getLocalPort()); + Socket s2 = ss.accept()) { + } + } + + // always returns bogus HTTP proxies + private static class HTTPProxySelector extends ProxySelector { + @Override + public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {} + + @Override + public List select(URI uri) { + List proxies = new ArrayList<>(); + proxies.add(new Proxy(Proxy.Type.HTTP, + new InetSocketAddress("localhost", 0))); + proxies.add(new Proxy(Proxy.Type.HTTP, + new InetSocketAddress("localhost", 0))); + return proxies; + } + } + + private static class NullHTTPProxySelector extends ProxySelector { + @Override + public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {} + + @Override + public List select(URI uri) { + List proxies = new ArrayList<>(); + proxies.add(null); + proxies.add(new Proxy(Proxy.Type.HTTP, + new InetSocketAddress("localhost", 0))); + return proxies; + } + } +} From cdf8c27ddb03484725a28ecc04b87510822d98e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Borggr=C3=A9n-Franck?= Date: Wed, 25 Feb 2015 14:30:02 +0100 Subject: [PATCH 17/29] 8014678: Spurious AccessControlException thrown in java.lang.Class.getEnclosingMethod() Reviewed-by: ahgross, mchung, psandoz --- .../share/classes/java/lang/Class.java | 24 +++++++-- ...closingConstructorWithSecurityManager.java | 50 +++++++++++++++++++ .../EnclosingMethodWithSecurityManager.java | 50 +++++++++++++++++++ 3 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 jdk/test/java/lang/Class/getEnclosingConstructor/EnclosingConstructorWithSecurityManager.java create mode 100644 jdk/test/java/lang/Class/getEnclosingMethod/EnclosingMethodWithSecurityManager.java diff --git a/jdk/src/java.base/share/classes/java/lang/Class.java b/jdk/src/java.base/share/classes/java/lang/Class.java index 3a0c3fdf3e6..258ec369ce5 100644 --- a/jdk/src/java.base/share/classes/java/lang/Class.java +++ b/jdk/src/java.base/share/classes/java/lang/Class.java @@ -1063,16 +1063,24 @@ public final class Class implements java.io.Serializable, parameterClasses[i] = toClass(parameterTypes[i]); // Perform access check - Class enclosingCandidate = enclosingInfo.getEnclosingClass(); + final Class enclosingCandidate = enclosingInfo.getEnclosingClass(); enclosingCandidate.checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true); + // Client is ok to access declared methods but j.l.Class might not be. + Method[] candidates = AccessController.doPrivileged( + new PrivilegedAction() { + @Override + public Method[] run() { + return enclosingCandidate.getDeclaredMethods(); + } + }); /* * Loop over all declared methods; match method name, * number of and type of parameters, *and* return * type. Matching return type is also necessary * because of covariant returns, etc. */ - for(Method m: enclosingCandidate.getDeclaredMethods()) { + for(Method m: candidates) { if (m.getName().equals(enclosingInfo.getName()) ) { Class[] candidateParamClasses = m.getParameterTypes(); if (candidateParamClasses.length == parameterClasses.length) { @@ -1215,14 +1223,22 @@ public final class Class implements java.io.Serializable, parameterClasses[i] = toClass(parameterTypes[i]); // Perform access check - Class enclosingCandidate = enclosingInfo.getEnclosingClass(); + final Class enclosingCandidate = enclosingInfo.getEnclosingClass(); enclosingCandidate.checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true); + // Client is ok to access declared methods but j.l.Class might not be. + Constructor[] candidates = AccessController.doPrivileged( + new PrivilegedAction[]>() { + @Override + public Constructor[] run() { + return enclosingCandidate.getDeclaredConstructors(); + } + }); /* * Loop over all declared constructors; match number * of and type of parameters. */ - for(Constructor c: enclosingCandidate.getDeclaredConstructors()) { + for(Constructor c: candidates) { Class[] candidateParamClasses = c.getParameterTypes(); if (candidateParamClasses.length == parameterClasses.length) { boolean matches = true; diff --git a/jdk/test/java/lang/Class/getEnclosingConstructor/EnclosingConstructorWithSecurityManager.java b/jdk/test/java/lang/Class/getEnclosingConstructor/EnclosingConstructorWithSecurityManager.java new file mode 100644 index 00000000000..1c81b09fa5a --- /dev/null +++ b/jdk/test/java/lang/Class/getEnclosingConstructor/EnclosingConstructorWithSecurityManager.java @@ -0,0 +1,50 @@ +/* + * 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 8014678 + * @run main EnclosingConstructorWithSecurityManager + * @run main/othervm EnclosingConstructorWithSecurityManager "WithSecurityManager" + */ + +public class EnclosingConstructorWithSecurityManager { + public static void main(String[] args) { + if (args.length == 1) { + System.setSecurityManager(new SecurityManager()); + } + + new Inner(); + Inner.theInner.getEnclosingConstructor(); + } + + public static class Inner { + public static Class theInner; + + public Inner() { + Object o = new Object() { + }; + Inner.theInner = o.getClass(); + } + } +} diff --git a/jdk/test/java/lang/Class/getEnclosingMethod/EnclosingMethodWithSecurityManager.java b/jdk/test/java/lang/Class/getEnclosingMethod/EnclosingMethodWithSecurityManager.java new file mode 100644 index 00000000000..fa14214cda6 --- /dev/null +++ b/jdk/test/java/lang/Class/getEnclosingMethod/EnclosingMethodWithSecurityManager.java @@ -0,0 +1,50 @@ +/* + * 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 8014678 + * @run main EnclosingMethodWithSecurityManager + * @run main/othervm EnclosingMethodWithSecurityManager "WithSecurityManager" + */ + +public class EnclosingMethodWithSecurityManager { + public static void main(String[] args) { + if (args.length == 1) { + System.setSecurityManager(new SecurityManager()); + } + + new Inner().setTheInner(); + Inner.theInner.getEnclosingMethod(); + } + + public static class Inner { + public static Class theInner; + + public void setTheInner() { + Object o = new Object() { + }; + Inner.theInner = o.getClass(); + } + } +} From 8749a5a08c590c2e9f2be2aabd787e3cec4ac40f Mon Sep 17 00:00:00 2001 From: Kumar Srinivasan Date: Wed, 25 Feb 2015 06:21:55 -0800 Subject: [PATCH 18/29] 8066185: VM crashed with SIGSEGV VirtualMemoryTracker::add_reserved_region Reviewed-by: coleenp, dholmes --- jdk/src/java.base/share/native/libjli/java.c | 20 +- jdk/test/tools/launcher/TestSpecialArgs.java | 330 +++++++++++-------- 2 files changed, 209 insertions(+), 141 deletions(-) diff --git a/jdk/src/java.base/share/native/libjli/java.c b/jdk/src/java.base/share/native/libjli/java.c index d988ac3cec2..27e828fd60a 100644 --- a/jdk/src/java.base/share/native/libjli/java.c +++ b/jdk/src/java.base/share/native/libjli/java.c @@ -651,9 +651,26 @@ static void SetJvmEnvironment(int argc, char **argv) { static const char* NMT_Env_Name = "NMT_LEVEL_"; - int i; for (i = 0; i < argc; i++) { + char *arg = argv[i]; + /* + * Since this must be a VM flag we stop processing once we see + * an argument the launcher would not have processed beyond (such + * as -version or -h), or an argument that indicates the following + * arguments are for the application (i.e. the main class name, or + * the -jar argument). + */ + if ((i > 0 && *arg != '-') + || JLI_StrCmp(arg, "-version") == 0 + || JLI_StrCmp(arg, "-fullversion") == 0 + || JLI_StrCmp(arg, "-help") == 0 + || JLI_StrCmp(arg, "-?") == 0 + || JLI_StrCmp(arg, "-jar") == 0 + || JLI_StrCmp(arg, "-X") == 0 + ) { + return; + } /* * The following case checks for "-XX:NativeMemoryTracking=value". * If value is non null, an environmental variable set to this value @@ -661,7 +678,6 @@ SetJvmEnvironment(int argc, char **argv) { * The argument is passed to the JVM, which will check validity. * The JVM is responsible for removing the env variable. */ - char *arg = argv[i]; if (JLI_StrCCmp(arg, "-XX:NativeMemoryTracking=") == 0) { int retval; // get what follows this parameter, include "=" diff --git a/jdk/test/tools/launcher/TestSpecialArgs.java b/jdk/test/tools/launcher/TestSpecialArgs.java index 04344e6adfb..0e35f028521 100644 --- a/jdk/test/tools/launcher/TestSpecialArgs.java +++ b/jdk/test/tools/launcher/TestSpecialArgs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, 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 @@ -23,12 +23,14 @@ /* * @test - * @bug 7124089 7131021 8042469 - * @summary Checks for MacOSX specific flags are accepted or rejected, and - * MacOSX platforms specific environment is consistent. + * @bug 7124089 7131021 8042469 8066185 + * @summary Checks for Launcher special flags, such as MacOSX specific flags, + * and JVM NativeMemoryTracking flags. * @compile -XDignore.symbol.file TestSpecialArgs.java EnvironmentVariables.java * @run main TestSpecialArgs */ +import java.io.File; +import java.io.FileNotFoundException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -36,10 +38,14 @@ import java.util.Set; public class TestSpecialArgs extends TestHelper { - public static void main(String... args) { + public static void main(String... args) throws Exception { + new TestSpecialArgs().run(args); + } + + @Test + void testDocking() { final Map envMap = new HashMap<>(); envMap.put("_JAVA_LAUNCHER_DEBUG", "true"); - TestResult tr = doExec(envMap, javaCmd, "-XstartOnFirstThread", "-version"); if (isMacOSX) { if (!tr.contains("In same thread")) { @@ -69,140 +75,10 @@ public class TestSpecialArgs extends TestHelper { throw new RuntimeException("Error: argument was accepted ????"); } } - - /* - * test argument : -XX:NativeMemoryTracking=value - * A JVM flag, comsumed by the JVM, but requiring launcher - * to set an environmental variable if and only if value is supplied. - * Test and order: - * 1) execute with valid parameter: -XX:NativeMemoryTracking=MyValue - * a) check for correct env variable name: "NMT_LEVEL_" + pid - * b) check that "MyValue" was found in local env. - * 2) execute with invalid parameter: -XX:NativeMemoryTracking= - * !) Won't find "NativeMemoryTracking:" - * Code to create env variable not executed. - * 3) execute with invalid parameter: -XX:NativeMemoryTracking - * !) Won't find "NativeMemoryTracking:" - * Code to create env variable not executed. - * 4) give and invalid value and check to make sure JVM commented - */ - { // NativeMemoryTracking - String launcherPidString = "launcher.pid="; - String envVarPidString = "TRACER_MARKER: NativeMemoryTracking: env var is NMT_LEVEL_"; - String NMT_Option_Value = "off"; - String myClassName = "helloworld"; - boolean haveLauncherPid = false; - - // === Run the tests === - - // ---Test 1a - tr = doExec(envMap,javaCmd, "-XX:NativeMemoryTracking=" + NMT_Option_Value, - "-version"); - - // get the PID from the env var we set for the JVM - String envVarPid = null; - for (String line : tr.testOutput) { - if (line.contains(envVarPidString)) { - int sindex = envVarPidString.length(); - envVarPid = line.substring(sindex); - break; - } - } - // did we find envVarPid? - if (envVarPid == null) { - System.out.println(tr); - throw new RuntimeException("Error: failed to find env Var Pid in tracking info"); - } - // we think we found the pid string. min test, not "". - if (envVarPid.length() < 1) { - System.out.println(tr); - throw new RuntimeException("Error: env Var Pid in tracking info is empty string"); - } - - /* - * On Linux, Launcher Tracking will print the PID. Use this info - * to validate what we got as the PID in the Launcher itself. - * Linux is the only one that prints this, and trying to get it - * here for win is awful. So let the linux test make sure we get - * the valid pid, and for non-linux, just make sure pid string is - * non-zero. - */ - if (isLinux) { - // get what the test says is the launcher pid - String launcherPid = null; - for (String line : tr.testOutput) { - int index = line.indexOf(launcherPidString); - if (index >= 0) { - int sindex = index + launcherPidString.length(); - int tindex = sindex + line.substring(sindex).indexOf("'"); - System.out.println("DEBUG INFO: sindex = " + sindex); - System.out.println("DEBUG INFO: searching substring: " + line.substring(sindex)); - System.out.println("DEBUG INFO: tindex = " + tindex); - // DEBUG INFO - System.out.println(tr); - launcherPid = line.substring(sindex, tindex); - break; - } - } - if (launcherPid == null) { - System.out.println(tr); - throw new RuntimeException("Error: failed to find launcher Pid in launcher tracking info"); - } - - // did we create the env var with the correct pid? - if (!launcherPid.equals(envVarPid)) { - System.out.println(tr); - System.out.println("Error: wrong pid in creating env var"); - System.out.println("Error Info: launcherPid = " + launcherPid); - System.out.println("Error Info: envVarPid = " + envVarPid); - throw new RuntimeException("Error: wrong pid in creating env var"); - } - } - - - // --- Test 1b - if (!tr.contains("NativeMemoryTracking: got value " + NMT_Option_Value)) { - System.out.println(tr); - throw new RuntimeException("Error: Valid param failed to set env variable"); - } - - // --- Test 2 - tr = doExec(envMap,javaCmd, "-XX:NativeMemoryTracking=", - "-version"); - if (tr.contains("NativeMemoryTracking:")) { - System.out.println(tr); - throw new RuntimeException("Error: invalid param caused env variable to be erroneously created"); - } - if (!tr.contains("Syntax error, expecting -XX:NativeMemoryTracking=")) { - System.out.println(tr); - throw new RuntimeException("Error: invalid param not checked by JVM"); - } - - // --- Test 3 - tr = doExec(envMap,javaCmd, "-XX:NativeMemoryTracking", - "-version"); - if (tr.contains("NativeMemoryTracking:")) { - System.out.println(tr); - throw new RuntimeException("Error: invalid param caused env variable to be erroneously created"); - } - if (!tr.contains("Syntax error, expecting -XX:NativeMemoryTracking=")) { - System.out.println(tr); - throw new RuntimeException("Error: invalid param not checked by JVM"); - } - // --- Test 4 - tr = doExec(envMap,javaCmd, "-XX:NativeMemoryTracking=BADVALUE", - "-version"); - if (!tr.contains("expecting -XX:NativeMemoryTracking")) { - System.out.println(tr); - throw new RuntimeException("Error: invalid param did not get JVM Syntax error message"); - } - - } // NativeMemoryTracking - - // MacOSX specific tests ensue...... - if (!isMacOSX) + if (!isMacOSX) { return; + } Set envToRemove = new HashSet<>(); Map map = System.getenv(); for (String s : map.keySet()) { @@ -225,11 +101,187 @@ public class TestSpecialArgs extends TestHelper { "APP_ICON_*", "TestAppIcon"); } - static void runTest(Set envToRemove, String... args) { + void runTest(Set envToRemove, String... args) { TestResult tr = doExec(null, envToRemove, args); if (!tr.isOK()) { System.err.println(tr.toString()); throw new RuntimeException("Test Fails"); } } + + @Test + void testNativeMemoryTracking() { + final Map envMap = new HashMap<>(); + envMap.put("_JAVA_LAUNCHER_DEBUG", "true"); + TestResult tr; + /* + * test argument : -XX:NativeMemoryTracking=value + * A JVM flag, comsumed by the JVM, but requiring launcher + * to set an environmental variable if and only if value is supplied. + * Test and order: + * 1) execute with valid parameter: -XX:NativeMemoryTracking=MyValue + * a) check for correct env variable name: "NMT_LEVEL_" + pid + * b) check that "MyValue" was found in local env. + * 2) execute with invalid parameter: -XX:NativeMemoryTracking= + * !) Won't find "NativeMemoryTracking:" + * Code to create env variable not executed. + * 3) execute with invalid parameter: -XX:NativeMemoryTracking + * !) Won't find "NativeMemoryTracking:" + * Code to create env variable not executed. + * 4) give and invalid value and check to make sure JVM commented + */ + String launcherPidString = "launcher.pid="; + String envVarPidString = "TRACER_MARKER: NativeMemoryTracking: env var is NMT_LEVEL_"; + String NMT_Option_Value = "off"; + String myClassName = "helloworld"; + boolean haveLauncherPid = false; + + // === Run the tests === + // ---Test 1a + tr = doExec(envMap, javaCmd, "-XX:NativeMemoryTracking=" + NMT_Option_Value, + "-version"); + + // get the PID from the env var we set for the JVM + String envVarPid = null; + for (String line : tr.testOutput) { + if (line.contains(envVarPidString)) { + int sindex = envVarPidString.length(); + envVarPid = line.substring(sindex); + break; + } + } + // did we find envVarPid? + if (envVarPid == null) { + System.out.println(tr); + throw new RuntimeException("Error: failed to find env Var Pid in tracking info"); + } + // we think we found the pid string. min test, not "". + if (envVarPid.length() < 1) { + System.out.println(tr); + throw new RuntimeException("Error: env Var Pid in tracking info is empty string"); + } + + /* + * On Linux, Launcher Tracking will print the PID. Use this info + * to validate what we got as the PID in the Launcher itself. + * Linux is the only one that prints this, and trying to get it + * here for win is awful. So let the linux test make sure we get + * the valid pid, and for non-linux, just make sure pid string is + * non-zero. + */ + if (isLinux) { + // get what the test says is the launcher pid + String launcherPid = null; + for (String line : tr.testOutput) { + int index = line.indexOf(launcherPidString); + if (index >= 0) { + int sindex = index + launcherPidString.length(); + int tindex = sindex + line.substring(sindex).indexOf("'"); + System.out.println("DEBUG INFO: sindex = " + sindex); + System.out.println("DEBUG INFO: searching substring: " + line.substring(sindex)); + System.out.println("DEBUG INFO: tindex = " + tindex); + // DEBUG INFO + System.out.println(tr); + launcherPid = line.substring(sindex, tindex); + break; + } + } + if (launcherPid == null) { + System.out.println(tr); + throw new RuntimeException("Error: failed to find launcher Pid in launcher tracking info"); + } + + // did we create the env var with the correct pid? + if (!launcherPid.equals(envVarPid)) { + System.out.println(tr); + System.out.println("Error: wrong pid in creating env var"); + System.out.println("Error Info: launcherPid = " + launcherPid); + System.out.println("Error Info: envVarPid = " + envVarPid); + throw new RuntimeException("Error: wrong pid in creating env var"); + } + } + + // --- Test 1b + if (!tr.contains("NativeMemoryTracking: got value " + NMT_Option_Value)) { + System.out.println(tr); + throw new RuntimeException("Error: Valid param failed to set env variable"); + } + + // --- Test 2 + tr = doExec(envMap, javaCmd, "-XX:NativeMemoryTracking=", + "-version"); + if (tr.contains("NativeMemoryTracking:")) { + System.out.println(tr); + throw new RuntimeException("Error: invalid param caused env variable to be erroneously created"); + } + if (!tr.contains("Syntax error, expecting -XX:NativeMemoryTracking=")) { + System.out.println(tr); + throw new RuntimeException("Error: invalid param not checked by JVM"); + } + + // --- Test 3 + tr = doExec(envMap, javaCmd, "-XX:NativeMemoryTracking", + "-version"); + if (tr.contains("NativeMemoryTracking:")) { + System.out.println(tr); + throw new RuntimeException("Error: invalid param caused env variable to be erroneously created"); + } + if (!tr.contains("Syntax error, expecting -XX:NativeMemoryTracking=")) { + System.out.println(tr); + throw new RuntimeException("Error: invalid param not checked by JVM"); + } + // --- Test 4 + tr = doExec(envMap, javaCmd, "-XX:NativeMemoryTracking=BADVALUE", + "-version"); + if (!tr.contains("expecting -XX:NativeMemoryTracking")) { + System.out.println(tr); + throw new RuntimeException("Error: invalid param did not get JVM Syntax error message"); + } + } + + @Test + void testNMArgumentProcessing() throws FileNotFoundException { + TestResult tr = null; + // the direct invokers of the VM + String options[] = { + "-version", "-fullversion", "-help", "-?", "-X" + }; + for (String option : options) { + tr = doExec(javaCmd, option, "-XX:NativeMemoryTracking=summary"); + checkTestResult(tr); + } + + // create a test jar + File jarFile = new File("test.jar"); + createJar(jarFile, "public static void main(String... args){}"); + + // ones that involve main-class of some sort + tr = doExec(javaCmd, "-jar", jarFile.getName(), + "-XX:NativeMemoryTracking=summary"); + checkTestResult(tr); + + tr = doExec(javaCmd, "-cp", jarFile.getName(), "Foo", + "-XX:NativeMemoryTracking=summary"); + checkTestResult(tr); + + final Map envMap = new HashMap<>(); + // checkwith CLASSPATH set ie. no -cp or -classpath + envMap.put("CLASSPATH", "."); + tr = doExec(envMap, javaCmd, "Foo", "-XX:NativeMemoryTracking=summary"); + checkTestResult(tr); + + // make sure a missing class is handled correctly, because the class + // resolution is performed by the JVM. + tr = doExec(javaCmd, "AbsentClass", "-XX:NativeMemoryTracking=summary"); + if (!tr.contains("Error: Could not find or load main class AbsentClass")) { + throw new RuntimeException("Test Fails"); + } + } + + void checkTestResult(TestResult tr) { + if (!tr.isOK()) { + System.err.println(tr.toString()); + throw new RuntimeException("Test Fails"); + } + } } From dcdbd326039e93a62c95c61dc40434628d04208b Mon Sep 17 00:00:00 2001 From: Mark Sheppard Date: Wed, 25 Feb 2015 17:05:56 +0000 Subject: [PATCH 19/29] 8046893: JNI exception pending in jdk/src/solaris/native/java/net: ExtendedOptionsImpl.c, PlainDatagramSocketImpl.c Reviewed-by: alanb, chegar --- jdk/src/java.base/unix/native/libnet/ExtendedOptionsImpl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/src/java.base/unix/native/libnet/ExtendedOptionsImpl.c b/jdk/src/java.base/unix/native/libnet/ExtendedOptionsImpl.c index 123c6575559..116d2e97d92 100644 --- a/jdk/src/java.base/unix/native/libnet/ExtendedOptionsImpl.c +++ b/jdk/src/java.base/unix/native/libnet/ExtendedOptionsImpl.c @@ -88,6 +88,7 @@ JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_init /* SocketFlow fields */ c = (*env)->FindClass(env, "jdk/net/SocketFlow"); + CHECK_NULL(c); /* status */ From 0f708456b2bfcf1be60252bddcb481f1a0c5fe2a Mon Sep 17 00:00:00 2001 From: Mark Sheppard Date: Wed, 25 Feb 2015 17:24:13 +0000 Subject: [PATCH 20/29] 8055204: Memory leak in jdk/src/windows/native/java/lang/java_props_md.c Reviewed-by: rriggs --- jdk/src/java.base/windows/native/libjava/java_props_md.c | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/src/java.base/windows/native/libjava/java_props_md.c b/jdk/src/java.base/windows/native/libjava/java_props_md.c index 2e80a71996e..05b668a7936 100644 --- a/jdk/src/java.base/windows/native/libjava/java_props_md.c +++ b/jdk/src/java.base/windows/native/libjava/java_props_md.c @@ -188,6 +188,7 @@ getJavaIDFromLangID(LANGID langID) free(elems[index]); } } else { + free(ret); ret = NULL; } From fc084beb84ae92016cf33300353a14c2c0f7cdd0 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Wed, 25 Feb 2015 18:41:07 +0100 Subject: [PATCH 21/29] 8072645: java.util.logging should use java.time to get more precise time stamps J.u.logging uses j.t.Instant to store LogRecord time stamps. XMLFormatter format is updated to allow for a new optional element containing a nano second adjustment. SimpleFormatter passes a ZonedDateTime object to String.format. LogRecord getMillis/setMillis are deprecated, replaced by getInstant/setInstant. Co-authored-by: Peter Levart Reviewed-by: scolebourne, plevart, rriggs --- .../sun/util/logging/LoggingSupport.java | 11 +- .../sun/util/logging/PlatformLogger.java | 15 +- .../classes/java/util/logging/LogRecord.java | 164 ++++++-- .../java/util/logging/SimpleFormatter.java | 32 +- .../java/util/logging/XMLFormatter.java | 90 ++++- .../lambda/LogGeneratedClassesTest.java | 22 +- .../util/logging/FileHandlerLongLimit.java | 19 +- .../LogRecordWithNanos.java | 143 +++++++ .../LogRecordWithNanosAPI.java | 308 +++++++++++++++ .../SerializeLogRecord.java | 363 ++++++++++++++++++ .../SimpleFormatterNanos.java | 155 ++++++++ .../XmlFormatterNanos.java | 274 +++++++++++++ 12 files changed, 1535 insertions(+), 61 deletions(-) create mode 100644 jdk/test/java/util/logging/HigherResolutionTimeStamps/LogRecordWithNanos.java create mode 100644 jdk/test/java/util/logging/HigherResolutionTimeStamps/LogRecordWithNanosAPI.java create mode 100644 jdk/test/java/util/logging/HigherResolutionTimeStamps/SerializeLogRecord.java create mode 100644 jdk/test/java/util/logging/HigherResolutionTimeStamps/SimpleFormatterNanos.java create mode 100644 jdk/test/java/util/logging/HigherResolutionTimeStamps/XmlFormatterNanos.java diff --git a/jdk/src/java.base/share/classes/sun/util/logging/LoggingSupport.java b/jdk/src/java.base/share/classes/sun/util/logging/LoggingSupport.java index 67b617dd693..3fb06be8541 100644 --- a/jdk/src/java.base/share/classes/sun/util/logging/LoggingSupport.java +++ b/jdk/src/java.base/share/classes/sun/util/logging/LoggingSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -29,7 +29,7 @@ package sun.util.logging; import java.lang.reflect.Field; import java.security.AccessController; import java.security.PrivilegedAction; -import java.util.Date; +import java.time.ZonedDateTime; /** * Internal API to support JRE implementation to detect if the java.util.logging @@ -145,6 +145,11 @@ public class LoggingSupport { return proxy.getLevelValue(level); } + // Since JDK 9, logging uses java.time to get more precise time stamps. + // It is possible to configure the simple format to print nano seconds (.%1$tN) + // by specifying: + // java.util.logging.SimpleFormatter.format=%1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS.%1$tN %1$Tp %2$s%n%4$s: %5$s%6$s%n + // in the logging configuration private static final String DEFAULT_FORMAT = "%1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS %1$Tp %2$s%n%4$s: %5$s%6$s%n"; @@ -171,7 +176,7 @@ public class LoggingSupport { if (format != null) { try { // validate the user-defined format string - String.format(format, new Date(), "", "", "", "", ""); + String.format(format, ZonedDateTime.now(), "", "", "", "", ""); } catch (IllegalArgumentException e) { // illegal syntax; fall back to the default format format = DEFAULT_FORMAT; diff --git a/jdk/src/java.base/share/classes/sun/util/logging/PlatformLogger.java b/jdk/src/java.base/share/classes/sun/util/logging/PlatformLogger.java index 4e8c48a1eac..03c48a4ffec 100644 --- a/jdk/src/java.base/share/classes/sun/util/logging/PlatformLogger.java +++ b/jdk/src/java.base/share/classes/sun/util/logging/PlatformLogger.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -32,8 +32,11 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.security.AccessController; import java.security.PrivilegedAction; +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.Arrays; -import java.util.Date; import java.util.HashMap; import java.util.Map; import sun.misc.JavaLangAccess; @@ -514,11 +517,9 @@ public class PlatformLogger { private static final String formatString = LoggingSupport.getSimpleFormat(false); // don't check logging.properties - - // minimize memory allocation - private Date date = new Date(); + private final ZoneId zoneId = ZoneId.systemDefault(); private synchronized String format(Level level, String msg, Throwable thrown) { - date.setTime(System.currentTimeMillis()); + ZonedDateTime zdt = ZonedDateTime.now(zoneId); String throwable = ""; if (thrown != null) { StringWriter sw = new StringWriter(); @@ -530,7 +531,7 @@ public class PlatformLogger { } return String.format(formatString, - date, + zdt, getCallerInfo(), name, level.name(), diff --git a/jdk/src/java.logging/share/classes/java/util/logging/LogRecord.java b/jdk/src/java.logging/share/classes/java/util/logging/LogRecord.java index 831f362f52a..b9887417299 100644 --- a/jdk/src/java.logging/share/classes/java/util/logging/LogRecord.java +++ b/jdk/src/java.logging/share/classes/java/util/logging/LogRecord.java @@ -24,10 +24,12 @@ */ package java.util.logging; +import java.time.Instant; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.io.*; +import java.time.Clock; import sun.misc.JavaLangAccess; import sun.misc.SharedSecrets; @@ -88,55 +90,94 @@ public class LogRecord implements java.io.Serializable { private static final ThreadLocal threadIds = new ThreadLocal<>(); /** - * @serial Logging message level + * Logging message level */ private Level level; /** - * @serial Sequence number + * Sequence number */ private long sequenceNumber; /** - * @serial Class that issued logging call + * Class that issued logging call */ private String sourceClassName; /** - * @serial Method that issued logging call + * Method that issued logging call */ private String sourceMethodName; /** - * @serial Non-localized raw message text + * Non-localized raw message text */ private String message; /** - * @serial Thread ID for thread that issued logging call. + * Thread ID for thread that issued logging call. */ private int threadID; /** - * @serial Event time in milliseconds since 1970 - */ - private long millis; - - /** - * @serial The Throwable (if any) associated with log message + * The Throwable (if any) associated with log message */ private Throwable thrown; /** - * @serial Name of the source Logger. + * Name of the source Logger. */ private String loggerName; /** - * @serial Resource bundle name to localized log message. + * Resource bundle name to localized log message. */ private String resourceBundleName; + /** + * Event time. + * @since 1.9 + */ + private Instant instant; + + /** + * @serialField level Level Logging message level + * @serialField sequenceNumber long Sequence number + * @serialField sourceClassName String Class that issued logging call + * @serialField sourceMethodName String Method that issued logging call + * @serialField message String Non-localized raw message text + * @serialField threadID int Thread ID for thread that issued logging call + * @serialField millis long Truncated event time in milliseconds since 1970 + * - calculated as getInstant().toEpochMilli(). + * The event time instant can be reconstructed using + * Instant.ofEpochSecond(millis/1000, (millis % 1000) * 1000_000 + nanoAdjustment) + * @serialField nanoAdjustment int Nanoseconds adjustment to the millisecond of + * event time - calculated as getInstant().getNano() % 1000_000 + * The event time instant can be reconstructed using + * Instant.ofEpochSecond(millis/1000, (millis % 1000) * 1000_000 + nanoAdjustment) + *

    + * Since: 1.9 + * @serialField thrown Throwable The Throwable (if any) associated with log + * message + * @serialField loggerName String Name of the source Logger + * @serialField resourceBundleName String Resource bundle name to localized + * log message + */ + private static final ObjectStreamField[] serialPersistentFields = + new ObjectStreamField[] { + new ObjectStreamField("level", Level.class), + new ObjectStreamField("sequenceNumber", long.class), + new ObjectStreamField("sourceClassName", String.class), + new ObjectStreamField("sourceMethodName", String.class), + new ObjectStreamField("message", String.class), + new ObjectStreamField("threadID", int.class), + new ObjectStreamField("millis", long.class), + new ObjectStreamField("nanoAdjustment", int.class), + new ObjectStreamField("thrown", Throwable.class), + new ObjectStreamField("loggerName", String.class), + new ObjectStreamField("resourceBundleName", String.class), + }; + private transient boolean needToInferCaller; private transient Object parameters[]; private transient ResourceBundle resourceBundle; @@ -164,7 +205,10 @@ public class LogRecord implements java.io.Serializable { * The sequence property will be initialized with a new unique value. * These sequence values are allocated in increasing order within a VM. *

    - * The millis property will be initialized to the current time. + * Since JDK 1.9, the event time is represented by an {@link Instant}. + * The instant property will be initialized to the {@linkplain + * Instant#now() current instant}, using the best available + * {@linkplain Clock#systemUTC() clock} on the system. *

    * The thread ID property will be initialized with a unique ID for * the current thread. @@ -173,6 +217,7 @@ public class LogRecord implements java.io.Serializable { * * @param level a logging level value * @param msg the raw non-localized logging message (may be null) + * @see java.time.Clock#systemUTC() */ public LogRecord(Level level, String msg) { this.level = Objects.requireNonNull(level); @@ -180,7 +225,7 @@ public class LogRecord implements java.io.Serializable { // Assign a thread ID and a unique sequence number. sequenceNumber = globalSequenceNumber.getAndIncrement(); threadID = defaultThreadID(); - millis = System.currentTimeMillis(); + instant = Instant.now(); needToInferCaller = true; } @@ -416,21 +461,63 @@ public class LogRecord implements java.io.Serializable { } /** - * Get event time in milliseconds since 1970. + * Get truncated event time in milliseconds since 1970. * - * @return event time in millis since 1970 + * @return truncated event time in millis since 1970 + * + * @implSpec This is equivalent to calling + * {@link #getInstant() getInstant().toEpochMilli()}. + * + * @deprecated To get the full nanosecond resolution event time, + * use {@link #getInstant()}. + * + * @see #getInstant() */ + @Deprecated public long getMillis() { - return millis; + return instant.toEpochMilli(); } /** * Set event time. * - * @param millis event time in millis since 1970 + * @param millis event time in millis since 1970. + * + * @implSpec This is equivalent to calling + * {@link #setInstant(java.time.Instant) + * setInstant(Instant.ofEpochMilli(millis))}. + * + * @deprecated To set event time with nanosecond resolution, + * use {@link #setInstant(java.time.Instant)}. + * + * @see #setInstant(java.time.Instant) */ + @Deprecated public void setMillis(long millis) { - this.millis = millis; + this.instant = Instant.ofEpochMilli(millis); + } + + /** + * Gets the instant that the event occurred. + * + * @return the instant that the event occurred. + * + * @since 1.9 + */ + public Instant getInstant() { + return instant; + } + + /** + * Sets the instant that the event occurred. + * + * @param instant the instant that the event occurred. + * + * @throws NullPointerException if {@code instant} is null. + * @since 1.9 + */ + public void setInstant(Instant instant) { + this.instant = Objects.requireNonNull(instant); } /** @@ -457,7 +544,7 @@ public class LogRecord implements java.io.Serializable { private static final long serialVersionUID = 5372048053134512534L; /** - * @serialData Default fields, followed by a two byte version number + * @serialData Serialized fields, followed by a two byte version number * (major byte, followed by minor byte), followed by information on * the log record parameter array. If there is no parameter array, * then -1 is written. If there is a parameter array (possible of zero @@ -467,8 +554,20 @@ public class LogRecord implements java.io.Serializable { * is written. */ private void writeObject(ObjectOutputStream out) throws IOException { - // We have to call defaultWriteObject first. - out.defaultWriteObject(); + // We have to write serialized fields first. + ObjectOutputStream.PutField pf = out.putFields(); + pf.put("level", level); + pf.put("sequenceNumber", sequenceNumber); + pf.put("sourceClassName", sourceClassName); + pf.put("sourceMethodName", sourceMethodName); + pf.put("message", message); + pf.put("threadID", threadID); + pf.put("millis", instant.toEpochMilli()); + pf.put("nanoAdjustment", instant.getNano() % 1000_000); + pf.put("thrown", thrown); + pf.put("loggerName", loggerName); + pf.put("resourceBundleName", resourceBundleName); + out.writeFields(); // Write our version number. out.writeByte(1); @@ -486,8 +585,21 @@ public class LogRecord implements java.io.Serializable { private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - // We have to call defaultReadObject first. - in.defaultReadObject(); + // We have to read serialized fields first. + ObjectInputStream.GetField gf = in.readFields(); + level = (Level) gf.get("level", null); + sequenceNumber = gf.get("sequenceNumber", 0L); + sourceClassName = (String) gf.get("sourceClassName", null); + sourceMethodName = (String) gf.get("sourceMethodName", null); + message = (String) gf.get("message", null); + threadID = gf.get("threadID", 0); + long millis = gf.get("millis", 0L); + int nanoOfMilli = gf.get("nanoAdjustment", 0); + instant = Instant.ofEpochSecond( + millis / 1000L, (millis % 1000L) * 1000_000L + nanoOfMilli); + thrown = (Throwable) gf.get("thrown", null); + loggerName = (String) gf.get("loggerName", null); + resourceBundleName = (String) gf.get("resourceBundleName", null); // Read version number. byte major = in.readByte(); diff --git a/jdk/src/java.logging/share/classes/java/util/logging/SimpleFormatter.java b/jdk/src/java.logging/share/classes/java/util/logging/SimpleFormatter.java index 12412f1c950..8beb465a59f 100644 --- a/jdk/src/java.logging/share/classes/java/util/logging/SimpleFormatter.java +++ b/jdk/src/java.logging/share/classes/java/util/logging/SimpleFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -27,8 +27,9 @@ package java.util.logging; import java.io.*; -import java.text.*; -import java.util.Date; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; import sun.util.logging.LoggingSupport; /** @@ -59,8 +60,8 @@ import sun.util.logging.LoggingSupport; public class SimpleFormatter extends Formatter { // format string for printing the log record - private static final String format = LoggingSupport.getSimpleFormat(); - private final Date dat = new Date(); + private final String format = LoggingSupport.getSimpleFormat(); + private final ZoneId zoneId = ZoneId.systemDefault(); /** * Format the given LogRecord. @@ -79,8 +80,9 @@ public class SimpleFormatter extends Formatter { * java.util.Formatter} format string specified in the * {@code java.util.logging.SimpleFormatter.format} property * or the default format. - *

  • {@code date} - a {@link Date} object representing - * {@linkplain LogRecord#getMillis event time} of the log record.
  • + *
  • {@code date} - a {@link ZonedDateTime} object representing + * {@linkplain LogRecord#getInstant() event time} of the log record + * in the {@link ZoneId#systemDefault()} system time zone.
  • *
  • {@code source} - a string representing the caller, if available; * otherwise, the logger's name.
  • *
  • {@code logger} - the logger's name.
  • @@ -129,6 +131,16 @@ public class SimpleFormatter extends Formatter { * Mar 22, 2011 1:11:31 PM MyClass fatal * SEVERE: several message with an exception * + *
  • {@code java.util.logging.SimpleFormatter.format="%1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS.%1$tN %1$Tp %2$s%n%4$s: %5$s%6$s%n"} + *

    Since JDK 1.9, {@code java.util.logging} uses {@link + * java.time.Clock#systemUTC() java.time} to create more precise time + * stamps. + * The format above can be used to add a {@code .%1$tN} to the + * date/time formatting so that nanoseconds will also be printed: + *

    +     *     Feb 06, 2015 5:33:10.279216000 PM example.Main main
    +     *     INFO: This is a test
    +     *     
  • * *

    This method can also be overridden in a subclass. * It is recommended to use the {@link Formatter#formatMessage} @@ -137,8 +149,10 @@ public class SimpleFormatter extends Formatter { * @param record the log record to be formatted. * @return a formatted log record */ + @Override public synchronized String format(LogRecord record) { - dat.setTime(record.getMillis()); + ZonedDateTime zdt = ZonedDateTime.ofInstant( + record.getInstant(), zoneId); String source; if (record.getSourceClassName() != null) { source = record.getSourceClassName(); @@ -159,7 +173,7 @@ public class SimpleFormatter extends Formatter { throwable = sw.toString(); } return String.format(format, - dat, + zdt, source, record.getLoggerName(), record.getLevel().getLocalizedLevelName(), diff --git a/jdk/src/java.logging/share/classes/java/util/logging/XMLFormatter.java b/jdk/src/java.logging/share/classes/java/util/logging/XMLFormatter.java index 075da9a3681..e39494135ca 100644 --- a/jdk/src/java.logging/share/classes/java/util/logging/XMLFormatter.java +++ b/jdk/src/java.logging/share/classes/java/util/logging/XMLFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -26,8 +26,9 @@ package java.util.logging; -import java.io.*; import java.nio.charset.Charset; +import java.time.Instant; +import java.time.format.DateTimeFormatter; import java.util.*; /** @@ -40,11 +41,70 @@ import java.util.*; * but it is recommended that it normally be used with UTF-8. The * character encoding can be set on the output Handler. * + * @implSpec Since JDK 1.9, instances of {@linkplain LogRecord} contain + * an {@link LogRecord#getInstant() Instant} which can have nanoseconds below + * the millisecond resolution. + * The DTD specification has been updated to allow for an optional + * {@code } element. By default, the XMLFormatter will compute the + * nanosecond adjustment below the millisecond resolution (using + * {@code LogRecord.getInstant().getNano() % 1000_000}) - and if this is not 0, + * this adjustment value will be printed in the new {@code } element. + * The event instant can then be reconstructed using + * {@code Instant.ofEpochSecond(millis/1000L, (millis % 1000L) * 1000_000L + nanos)} + * where {@code millis} and {@code nanos} represent the numbers serialized in + * the {@code } and {@code } elements, respectively. + *
    + * The {@code } element will now contain the whole instant as formatted + * by the {@link DateTimeFormatter#ISO_INSTANT DateTimeFormatter.ISO_INSTANT} + * formatter. + *

    + * For compatibility with old parsers, XMLFormatters can + * be configured to revert to the old format by specifying a + * {@code .useInstant = false} + * {@linkplain LogManager#getProperty(java.lang.String) property} in the + * logging configuration. When {@code useInstant} is {@code false}, the old + * formatting will be preserved. When {@code useInstant} is {@code true} + * (the default), the {@code } element will be printed and the + * {@code } element will contain the {@linkplain + * DateTimeFormatter#ISO_INSTANT formatted} instant. + *

    + * For instance, in order to configure plain instances of XMLFormatter to omit + * the new {@code } element, + * {@code java.util.logging.XMLFormatter.useInstant = false} can be specified + * in the logging configuration. + * * @since 1.4 */ public class XMLFormatter extends Formatter { - private LogManager manager = LogManager.getLogManager(); + private final LogManager manager = LogManager.getLogManager(); + private final boolean useInstant; + + /** + * Creates a new instance of XMLFormatter. + * + * @implSpec + * Since JDK 1.9, the XMLFormatter will print out the record {@linkplain + * LogRecord#getInstant() event time} as an Instant. This instant + * has the best resolution available on the system. The {@code } + * element will contain the instant as formatted by the {@link + * DateTimeFormatter#ISO_INSTANT}. + * In addition, an optional {@code } element containing a + * nanosecond adjustment will be printed if the instant contains some + * nanoseconds below the millisecond resolution. + *

    + * This new behavior can be turned off, and the old formatting restored, + * by specifying a property in the {@linkplain + * LogManager#getProperty(java.lang.String) logging configuration}. + * If {@code LogManager.getLogManager().getProperty( + * this.getClass().getName()+".useInstant")} is {@code "false"} or + * {@code "0"}, the old formatting will be restored. + */ + public XMLFormatter() { + useInstant = (manager == null) + || manager.getBooleanProperty( + this.getClass().getName()+".useInstant", true); + } // Append a two digit number. private void a2(StringBuilder sb, int x) { @@ -102,18 +162,35 @@ public class XMLFormatter extends Formatter { * @param record the log record to be formatted. * @return a formatted log record */ + @Override public String format(LogRecord record) { StringBuilder sb = new StringBuilder(500); sb.append("\n"); + final Instant instant = record.getInstant(); + sb.append(" "); - appendISO8601(sb, record.getMillis()); + if (useInstant) { + // If useInstant is true - we will print the instant in the + // date field, using the ISO_INSTANT formatter. + DateTimeFormatter.ISO_INSTANT.formatTo(instant, sb); + } else { + // If useInstant is false - we will keep the 'old' formating + appendISO8601(sb, instant.toEpochMilli()); + } sb.append("\n"); sb.append(" "); - sb.append(record.getMillis()); + sb.append(instant.toEpochMilli()); sb.append("\n"); + final int nanoAdjustment = instant.getNano() % 1000_000; + if (useInstant && nanoAdjustment != 0) { + sb.append(" "); + sb.append(nanoAdjustment); + sb.append("\n"); + } + sb.append(" "); sb.append(record.getSequenceNumber()); sb.append("\n"); @@ -223,6 +300,7 @@ public class XMLFormatter extends Formatter { * @param h The target handler (can be null) * @return a valid XML string */ + @Override public String getHead(Handler h) { StringBuilder sb = new StringBuilder(); String encoding; @@ -251,6 +329,7 @@ public class XMLFormatter extends Formatter { sb.append(encoding); sb.append("\""); sb.append(" standalone=\"no\"?>\n"); + sb.append("\n"); sb.append("\n"); return sb.toString(); @@ -262,6 +341,7 @@ public class XMLFormatter extends Formatter { * @param h The target handler (can be null) * @return a valid XML string */ + @Override public String getTail(Handler h) { return "\n"; } diff --git a/jdk/test/java/lang/invoke/lambda/LogGeneratedClassesTest.java b/jdk/test/java/lang/invoke/lambda/LogGeneratedClassesTest.java index 33acc50d667..1030d27f7fe 100644 --- a/jdk/test/java/lang/invoke/lambda/LogGeneratedClassesTest.java +++ b/jdk/test/java/lang/invoke/lambda/LogGeneratedClassesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -32,6 +32,7 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.function.Predicate; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -235,8 +236,23 @@ public class LogGeneratedClassesTest extends LUtils { .filter(s -> s.startsWith("WARNING: Exception")) .count(), 2, "show error each capture"); - // dumpLong/com/example/nosense/nosense - assertEquals(Files.walk(Paths.get("dumpLong")).count(), 5, "Two lambda captured failed to log"); + // dumpLong/com/example/nonsense/nonsense + Path dumpPath = Paths.get("dumpLong/com/example/nonsense"); + Predicate filter = p -> p.getParent() == null || dumpPath.startsWith(p) || p.startsWith(dumpPath); + boolean debug = true; + if (debug) { + Files.walk(Paths.get("dumpLong")) + .forEachOrdered(p -> { + if (filter.test(p)) { + System.out.println("accepted: " + p.toString()); + } else { + System.out.println("filetered out: " + p.toString()); + } + }); + } + assertEquals(Files.walk(Paths.get("dumpLong")) + .filter(filter) + .count(), 5, "Two lambda captured failed to log"); tr.assertZero("Should still return 0"); } } diff --git a/jdk/test/java/util/logging/FileHandlerLongLimit.java b/jdk/test/java/util/logging/FileHandlerLongLimit.java index b5b1cfa5b01..67e4001fb81 100644 --- a/jdk/test/java/util/logging/FileHandlerLongLimit.java +++ b/jdk/test/java/util/logging/FileHandlerLongLimit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -346,26 +346,29 @@ public class FileHandlerLongLimit { assertEquals(0, getWritten(metered), "written"); // now we're going to publish a series of log records + // we're using the same log record over and over to make + // sure we get the same amount of bytes. String msg = "this is at least 10 chars long"; - fh.publish(new LogRecord(Level.SEVERE, msg)); + LogRecord record = new LogRecord(Level.SEVERE, msg); + fh.publish(record); fh.flush(); long w = getWritten(metered); long offset = getWritten(metered); System.out.println("first offset is: " + offset); - fh.publish(new LogRecord(Level.SEVERE, msg)); + fh.publish(record); fh.flush(); offset = getWritten(metered) - w; w = getWritten(metered); System.out.println("second offset is: " + offset); - fh.publish(new LogRecord(Level.SEVERE, msg)); + fh.publish(record); fh.flush(); offset = getWritten(metered) - w; w = getWritten(metered); System.out.println("third offset is: " + offset); - fh.publish(new LogRecord(Level.SEVERE, msg)); + fh.publish(record); fh.flush(); offset = getWritten(metered) - w; System.out.println("fourth offset is: " + offset); @@ -377,7 +380,7 @@ public class FileHandlerLongLimit { // publish one more log record. we should still be just beneath // the limit - fh.publish(new LogRecord(Level.SEVERE, msg)); + fh.publish(record); fh.flush(); assertEquals(w+offset, getWritten(metered), "written"); @@ -392,9 +395,9 @@ public class FileHandlerLongLimit { // writing the first log record or just before writing the next // one. We publich two - so we're sure that the log must have // rotated. - fh.publish(new LogRecord(Level.SEVERE, msg)); + fh.publish(record); fh.flush(); - fh.publish(new LogRecord(Level.SEVERE, msg)); + fh.publish(record); fh.flush(); // Check that fh.meter is a different instance of MeteredStream. diff --git a/jdk/test/java/util/logging/HigherResolutionTimeStamps/LogRecordWithNanos.java b/jdk/test/java/util/logging/HigherResolutionTimeStamps/LogRecordWithNanos.java new file mode 100644 index 00000000000..bdaf2054e21 --- /dev/null +++ b/jdk/test/java/util/logging/HigherResolutionTimeStamps/LogRecordWithNanos.java @@ -0,0 +1,143 @@ +/* + * 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.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.SimpleFormatter; + +/** + * @test + * @bug 8072645 + * @summary tests that LogRecord has nanos... + * @run main LogRecordWithNanos + * @author danielfuchs + */ +public class LogRecordWithNanos { + + static final int MILLIS_IN_SECOND = 1000; + static final int NANOS_IN_MILLI = 1000_000; + static final int NANOS_IN_SECOND = 1000_000_000; + + static final boolean verbose = false; + + static final class TestAssertException extends RuntimeException { + TestAssertException(String msg) { super(msg); } + } + + private static void assertEquals(long expected, long received, String msg) { + if (expected != received) { + throw new TestAssertException("Unexpected result for " + msg + + ".\n\texpected: " + expected + + "\n\tactual: " + received); + } else if (verbose) { + System.out.println("Got expected " + msg + ": " + received); + } + } + + /** + * Serializes a log record, then deserializes it and check that both + * records match. + * @param record the log record to serialize & deserialize. + * @throws IOException Unexpected. + * @throws ClassNotFoundException Unexpected. + */ + public static void test(LogRecord record) + throws IOException, ClassNotFoundException { + + // Format the given logRecord using the SimpleFormatter + SimpleFormatter formatter = new SimpleFormatter(); + String str = formatter.format(record); + + // Serialize the given LogRecord + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + final ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(record); + oos.flush(); + oos.close(); + + // First checks that the log record can be deserialized + final ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + final ObjectInputStream ois = new ObjectInputStream(bais); + final LogRecord record2 = (LogRecord)ois.readObject(); + + assertEquals(record.getMillis(), record2.getMillis(), "getMillis()"); + assertEquals(record.getInstant().getEpochSecond(), + record2.getInstant().getEpochSecond(), + "getInstant().getEpochSecond()"); + assertEquals(record.getInstant().getNano(), + record2.getInstant().getNano(), + "getInstant().getNano()"); + assertEquals(record.getInstant().toEpochMilli(), + record2.getInstant().toEpochMilli(), + "getInstant().toEpochMilli()"); + assertEquals(record.getMillis(), + record.getInstant().toEpochMilli(), + "getMillis()/getInstant().toEpochMilli()"); + assertEquals(record2.getMillis(), + record2.getInstant().toEpochMilli(), + "getMillis()/getInstant().toEpochMilli()"); + assertEquals((record.getMillis()%MILLIS_IN_SECOND)*NANOS_IN_MILLI + + (record.getInstant().getNano() % NANOS_IN_MILLI), + record.getInstant().getNano(), + "record.getMillis()%1000)*1000_000" + + " + record.getInstant().getNano()%1000_000 / getInstant().getNano()"); + assertEquals((record2.getMillis()%MILLIS_IN_SECOND)*NANOS_IN_MILLI + + (record2.getInstant().getNano() % NANOS_IN_MILLI), + record2.getInstant().getNano(), + "record2.getMillis()%1000)*1000_000" + + " + record2.getInstant().getNano()%1000_000 / getInstant().getNano()"); + + // Format the deserialized LogRecord using the SimpleFormatter, and + // check that the string representation obtained matches the string + // representation of the original LogRecord + String str2 = formatter.format(record2); + if (!str.equals(str2)) + throw new RuntimeException("Unexpected values in deserialized object:" + + "\n\tExpected: " + str + + "\n\tRetrieved: "+str); + + } + + + public static void main(String[] args) throws Exception { + int count=0; + for (int i=0; i<1000; i++) { + LogRecord record = new LogRecord(Level.INFO, "Java Version: {0}"); + record.setLoggerName("test"); + record.setParameters(new Object[] {System.getProperty("java.version")}); + if (record.getInstant().getNano() % 1000_000 != 0) { + count++; + } + test(record); + } + if (count == 0) { + throw new RuntimeException("Expected at least one record to have nanos"); + } + System.out.println(count + "/1000 records had nano adjustment."); + } + +} diff --git a/jdk/test/java/util/logging/HigherResolutionTimeStamps/LogRecordWithNanosAPI.java b/jdk/test/java/util/logging/HigherResolutionTimeStamps/LogRecordWithNanosAPI.java new file mode 100644 index 00000000000..0c6cfce652b --- /dev/null +++ b/jdk/test/java/util/logging/HigherResolutionTimeStamps/LogRecordWithNanosAPI.java @@ -0,0 +1,308 @@ +/* + * 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.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.time.Instant; +import java.util.Objects; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.SimpleFormatter; + +/** + * @test + * @bug 8072645 + * @summary tests the new methods added to LogRecord. + * @run main LogRecordWithNanosAPI + * @author danielfuchs + */ +public class LogRecordWithNanosAPI { + + static final int MILLIS_IN_SECOND = 1000; + static final int NANOS_IN_MILLI = 1000_000; + static final int NANOS_IN_SECOND = 1000_000_000; + + static final boolean verbose = true; + + static final class TestAssertException extends RuntimeException { + TestAssertException(String msg) { super(msg); } + } + + private static void assertEquals(long expected, long received, String msg) { + if (expected != received) { + throw new TestAssertException("Unexpected result for " + msg + + ".\n\texpected: " + expected + + "\n\tactual: " + received); + } else if (verbose) { + System.out.println("Got expected " + msg + ": " + received); + } + } + + private static void assertEquals(Object expected, Object received, String msg) { + if (!Objects.equals(expected, received)) { + throw new TestAssertException("Unexpected result for " + msg + + ".\n\texpected: " + expected + + "\n\tactual: " + received); + } else if (verbose) { + System.out.println("Got expected " + msg + ": " + received); + } + } + + // The nano second fractional part of a second, contained in a time expressed + // as a number of millisecond from the epoch. + private static long nanoInSecondFromEpochMilli(long millis) { + return (((millis%MILLIS_IN_SECOND) + MILLIS_IN_SECOND)%MILLIS_IN_SECOND)*NANOS_IN_MILLI; + } + + /** + * Serializes a log record, then deserializes it and check that both + * records match. + * @param record the log record to serialize & deserialize. + * @param hasExceedingNanos whether the record has a nano adjustment whose + * value exceeds 1ms. + * @throws IOException Unexpected. + * @throws ClassNotFoundException Unexpected. + */ + public static void test(LogRecord record, boolean hasExceedingNanos) + throws IOException, ClassNotFoundException { + + // Format the given logRecord using the SimpleFormatter + SimpleFormatter formatter = new SimpleFormatter(); + String str = formatter.format(record); + + // Serialize the given LogRecord + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + final ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(record); + oos.flush(); + oos.close(); + + // First checks that the log record can be deserialized + final ByteArrayInputStream bais = + new ByteArrayInputStream(baos.toByteArray()); + final ObjectInputStream ois = new ObjectInputStream(bais); + final LogRecord record2 = (LogRecord)ois.readObject(); + + assertEquals(record.getMillis(), record2.getMillis(), "getMillis()"); + assertEquals(record.getInstant().getEpochSecond(), + record2.getInstant().getEpochSecond(), + "getInstant().getEpochSecond()"); + assertEquals(record.getInstant().getNano(), + record2.getInstant().getNano(), + "getInstant().getNano()"); + assertEquals(record.getInstant().toEpochMilli(), + record2.getInstant().toEpochMilli(), + "getInstant().toEpochMilli()"); + long millis = record.getMillis(); + millis = hasExceedingNanos + ? Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, + (millis%MILLIS_IN_SECOND)*NANOS_IN_MILLI + + record.getInstant().getNano() % NANOS_IN_MILLI).toEpochMilli() + : millis; + assertEquals(millis, record.getInstant().toEpochMilli(), + "getMillis()/getInstant().toEpochMilli()"); + millis = record2.getMillis(); + millis = hasExceedingNanos + ? Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, + (millis%MILLIS_IN_SECOND)*NANOS_IN_MILLI + + record2.getInstant().getNano() % NANOS_IN_MILLI).toEpochMilli() + : millis; + assertEquals(millis, record2.getInstant().toEpochMilli(), + "getMillis()/getInstant().toEpochMilli()"); + long nanos = nanoInSecondFromEpochMilli(record.getMillis()) + + record.getInstant().getNano() % NANOS_IN_MILLI; + assertEquals(nanos, record.getInstant().getNano(), + "nanoInSecondFromEpochMilli(record.getMillis())" + + " + record.getInstant().getNano() % NANOS_IN_MILLI /getInstant().getNano()"); + nanos = nanoInSecondFromEpochMilli(record2.getMillis()) + + record2.getInstant().getNano() % NANOS_IN_MILLI; + assertEquals(nanos, record2.getInstant().getNano(), + "nanoInSecondFromEpochMilli(record2.getMillis())" + + " + record2.getInstant().getNano() % NANOS_IN_MILLI /getInstant().getNano()"); + + // Format the deserialized LogRecord using the SimpleFormatter, and + // check that the string representation obtained matches the string + // representation of the original LogRecord + String str2 = formatter.format(record2); + if (!str.equals(str2)) + throw new RuntimeException("Unexpected values in deserialized object:" + + "\n\tExpected: " + str + + "\n\tRetrieved: "+str); + + } + + + public static void main(String[] args) throws Exception { + int count=0; + LogRecord record = new LogRecord(Level.INFO, "Java Version: {0}"); + record.setLoggerName("test"); + record.setParameters(new Object[] {System.getProperty("java.version")}); + final int nanos = record.getInstant().getNano() % NANOS_IN_MILLI; + final long millis = record.getMillis(); + final Instant instant = record.getInstant(); + if (millis != instant.toEpochMilli()) { + throw new RuntimeException("Unexpected millis: " + + record.getMillis()); + } + test(record, false); + + // nano adjustment < 1ms (canonical case) + int newNanos = (nanos + 111111) % NANOS_IN_MILLI; + record.setInstant(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, + (millis % MILLIS_IN_SECOND) * NANOS_IN_MILLI + newNanos)); + assertEquals(newNanos, record.getInstant().getNano() % NANOS_IN_MILLI, + "record.getInstant().getNano() % NANOS_IN_MILLI"); + assertEquals(millis, record.getMillis(), "record.getMillis()"); + assertEquals(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, + (millis%MILLIS_IN_SECOND)*NANOS_IN_MILLI + newNanos), + record.getInstant(), "record.getInstant()"); + test(record, false); + assertEquals(newNanos, record.getInstant().getNano() % NANOS_IN_MILLI, + "record.getInstant().getNano() % NANOS_IN_MILLI"); + assertEquals(millis, record.getMillis(), "record.getMillis()"); + assertEquals(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, + (millis%MILLIS_IN_SECOND)*NANOS_IN_MILLI + newNanos), + record.getInstant(), "record.getInstant()"); + + // nano adjustment > 1ms - non canonical - should still work + int newExceedingNanos = 2111_111; + record.setInstant(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, + (millis % MILLIS_IN_SECOND) * NANOS_IN_MILLI + newExceedingNanos)); + assertEquals(newExceedingNanos % NANOS_IN_MILLI, + record.getInstant().getNano() % NANOS_IN_MILLI, + "record.getInstant().getNano() % NANOS_IN_MILLI"); + assertEquals(millis + newExceedingNanos / NANOS_IN_MILLI, + record.getMillis(), "record.getMillis()"); + assertEquals(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, + (millis%MILLIS_IN_SECOND)*NANOS_IN_MILLI + newExceedingNanos), + record.getInstant(), "record.getInstant()"); + test(record, true); + assertEquals(newExceedingNanos % NANOS_IN_MILLI, + record.getInstant().getNano() % NANOS_IN_MILLI, + "record.getInstant().getNano() % NANOS_IN_MILLI"); + assertEquals(millis + newExceedingNanos / NANOS_IN_MILLI, + record.getMillis(), "record.getMillis()"); + assertEquals(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, + (millis%MILLIS_IN_SECOND)*NANOS_IN_MILLI + newExceedingNanos), + record.getInstant(), "record.getInstant()"); + + // nano adjustement > 1s - non canonical - should still work + newExceedingNanos = 1111_111_111; + record.setInstant(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, + (millis % MILLIS_IN_SECOND) * NANOS_IN_MILLI + newExceedingNanos)); + assertEquals(newExceedingNanos % NANOS_IN_MILLI, + record.getInstant().getNano() % NANOS_IN_MILLI, + "record.getInstant().getNano() % NANOS_IN_MILLI"); + assertEquals(millis + newExceedingNanos / NANOS_IN_MILLI, + record.getMillis(), "record.getMillis()"); + assertEquals(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, + (millis%MILLIS_IN_SECOND)*NANOS_IN_MILLI + newExceedingNanos), + record.getInstant(), "record.getInstant()"); + test(record, true); + assertEquals(newExceedingNanos % NANOS_IN_MILLI, + record.getInstant().getNano() % NANOS_IN_MILLI, + "record.getInstant().getNano() % NANOS_IN_MILLI"); + assertEquals(millis + newExceedingNanos / NANOS_IN_MILLI, + record.getMillis(), "record.getMillis()"); + assertEquals(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, + (millis%MILLIS_IN_SECOND)*NANOS_IN_MILLI + newExceedingNanos), + record.getInstant(), "record.getInstant()"); + + // nano adjustement < 0 - non canonical - should still work + newExceedingNanos = -1; + record.setInstant(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, + (millis % MILLIS_IN_SECOND) * NANOS_IN_MILLI + newExceedingNanos)); + assertEquals(newExceedingNanos + NANOS_IN_MILLI, + record.getInstant().getNano() % NANOS_IN_MILLI, + "record.getInstant().getNano() % NANOS_IN_MILLI"); + assertEquals(millis -1, record.getMillis(), "record.getMillis()"); + assertEquals(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, + (millis%MILLIS_IN_SECOND)*NANOS_IN_MILLI + newExceedingNanos), + record.getInstant(), "record.getInstant()"); + test(record, true); + record.setInstant(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, + (millis % MILLIS_IN_SECOND) * NANOS_IN_MILLI + newExceedingNanos)); + assertEquals(millis -1, record.getMillis(), "record.getMillis()"); + assertEquals(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, + (millis%MILLIS_IN_SECOND)*NANOS_IN_MILLI + newExceedingNanos), + record.getInstant(), "record.getInstant()"); + + // setMillis + record.setMillis(millis-1); + assertEquals(millis-1, record.getInstant().toEpochMilli(), + "record.getInstant().toEpochMilli()"); + assertEquals(millis-1, record.getMillis(), + "record.getMillis()"); + assertEquals(0, record.getInstant().getNano() % NANOS_IN_MILLI, + "record.getInstant().getNano() % NANOS_IN_MILLI"); + test(record, false); + assertEquals(millis-1, record.getInstant().toEpochMilli(), + "record.getInstant().toEpochMilli()"); + assertEquals(millis-1, record.getMillis(), + "record.getMillis()"); + assertEquals(0, record.getInstant().getNano() % NANOS_IN_MILLI, + "record.getInstant().getNano() % NANOS_IN_MILLI"); + + // setMillis to 0 + record.setMillis(0); + assertEquals(0, record.getInstant().toEpochMilli(), + "record.getInstant().toEpochMilli()"); + assertEquals(0, record.getMillis(), + "record.getMillis()"); + assertEquals(0, record.getInstant().getNano() % NANOS_IN_MILLI, + "record.getInstant().getNano() % NANOS_IN_MILLI"); + test(record, false); + assertEquals(0, record.getInstant().toEpochMilli(), + "record.getInstant().toEpochMilli()"); + assertEquals(0, record.getMillis(), + "record.getMillis()"); + assertEquals(0, record.getInstant().getNano() % NANOS_IN_MILLI, + "record.getInstant().getNano() % NANOS_IN_MILLI"); + + // setMillis to -1 + record.setMillis(-1); + assertEquals(-1, record.getInstant().toEpochMilli(), + "record.getInstant().toEpochMilli()"); + assertEquals(-1, record.getMillis(), + "record.getMillis()"); + assertEquals(0, record.getInstant().getNano() % NANOS_IN_MILLI, + "record.getInstant().getNano() % NANOS_IN_MILLI"); + test(record, false); + assertEquals(-1, record.getInstant().toEpochMilli(), + "record.getInstant().toEpochMilli()"); + assertEquals(-1, record.getMillis(), + "record.getMillis()"); + assertEquals(0, record.getInstant().getNano() % NANOS_IN_MILLI, + "record.getInstant().getNano() % NANOS_IN_MILLI"); + + try { + record.setInstant(null); + } catch (NullPointerException x) { + System.out.println("Got expected NPE when trying to call record.setInstant(null): " + x); + } + + } + +} diff --git a/jdk/test/java/util/logging/HigherResolutionTimeStamps/SerializeLogRecord.java b/jdk/test/java/util/logging/HigherResolutionTimeStamps/SerializeLogRecord.java new file mode 100644 index 00000000000..69f6cdd8aab --- /dev/null +++ b/jdk/test/java/util/logging/HigherResolutionTimeStamps/SerializeLogRecord.java @@ -0,0 +1,363 @@ +/* + * 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.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.time.ZoneId; +import java.util.Base64; +import java.util.Locale; +import java.util.TimeZone; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.SimpleFormatter; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Stream; + +/** + * @test + * @bug 8072645 + * @summary tests the compatibility of LogRecord serial form between + * JDK 8 and JDK 9. Ideally this test should be run on both platforms. + * (It is designed to run on both). + * @run main/othervm SerializeLogRecord + * @author danielfuchs + */ +public class SerializeLogRecord { + + /** + * Serializes a log record, encode the serialized bytes in base 64, and + * prints pseudo java code that can be cut and pasted into this test. + * @param record the log record to serialize, encode in base 64, and for + * which test data will be generated. + * @return A string containing the generated pseudo java code. + * @throws IOException Unexpected. + * @throws ClassNotFoundException Unexpected. + */ + public static String generate(LogRecord record) throws IOException, ClassNotFoundException { + + // Format the given logRecord using the SimpleFormatter + SimpleFormatter formatter = new SimpleFormatter(); + String str = formatter.format(record); + + // Serialize the given LogRecord + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + final ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(record); + oos.flush(); + oos.close(); + + // Now we're going to perform a number of smoke tests before + // generating the Java pseudo code. + // + // First checks that the log record can be deserialized + final ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + final ObjectInputStream ois = new ObjectInputStream(bais); + final LogRecord record2 = (LogRecord)ois.readObject(); + + // Format the deserialized LogRecord using the SimpleFormatter, and + // check that the string representation obtained matches the string + // representation of the original LogRecord + String str2 = formatter.format(record2); + if (!str.equals(str2)) throw new RuntimeException("Unexpected values in deserialized object:" + + "\n\tExpected: " + str + + "\n\tRetrieved: "+str); + + // Now get a Base64 string representation of the serialized bytes. + final String base64 = Base64.getEncoder().encodeToString(baos.toByteArray()); + + // Check that we can deserialize a log record from the Base64 string + // representation we just computed. + final ByteArrayInputStream bais2 = new ByteArrayInputStream(Base64.getDecoder().decode(base64)); + final ObjectInputStream ois2 = new ObjectInputStream(bais2); + final LogRecord record3 = (LogRecord)ois2.readObject(); + + // Format the new deserialized LogRecord using the SimpleFormatter, and + // check that the string representation obtained matches the string + // representation of the original LogRecord + String str3 = formatter.format(record3); + if (!str.equals(str3)) throw new RuntimeException("Unexpected values in deserialized object:" + + "\n\tExpected: " + str + + "\n\tRetrieved: "+str); + //System.out.println(base64); + //System.out.println(); + + // Generates the Java Pseudo code that can be cut & pasted into + // this test (see Jdk8SerializedLog and Jdk9SerializedLog below) + final StringBuilder sb = new StringBuilder(); + sb.append(" /**").append('\n'); + sb.append(" * Base64 encoded string for LogRecord object.").append('\n'); + sb.append(" * Java version: ").append(System.getProperty("java.version")).append('\n'); + sb.append(" **/").append('\n'); + sb.append(" final String base64 = ").append("\n "); + final int last = base64.length() - 1; + for (int i=0; i TestCase.valueOf(x)).forEach((x) -> { + switch(x) { + case GENERATE: generate(); break; + case TESTJDK8: Jdk8SerializedLog.test(); break; + case TESTJDK9: Jdk9SerializedLog.test(); break; + } + }); + } +} diff --git a/jdk/test/java/util/logging/HigherResolutionTimeStamps/SimpleFormatterNanos.java b/jdk/test/java/util/logging/HigherResolutionTimeStamps/SimpleFormatterNanos.java new file mode 100644 index 00000000000..17858487a04 --- /dev/null +++ b/jdk/test/java/util/logging/HigherResolutionTimeStamps/SimpleFormatterNanos.java @@ -0,0 +1,155 @@ +/* + * 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.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Locale; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.SimpleFormatter; + +/** + * @test + * @bug 8072645 + * @summary tests that SimpleFormatter can print out dates with the new + * nanosecond precision. + * @run main/othervm SimpleFormatterNanos + * @author danielfuchs + */ +public class SimpleFormatterNanos { + + static final int MILLIS_IN_SECOND = 1000; + static final int NANOS_IN_MILLI = 1000_000; + static final int NANOS_IN_MICRO = 1000; + static final int NANOS_IN_SECOND = 1000_000_000; + + static final boolean verbose = true; + + static final class TestAssertException extends RuntimeException { + TestAssertException(String msg) { super(msg); } + } + + private static void assertEquals(long expected, long received, String msg) { + if (expected != received) { + throw new TestAssertException("Unexpected result for " + msg + + ".\n\texpected: " + expected + + "\n\tactual: " + received); + } else if (verbose) { + System.out.println("Got expected " + msg + ": " + received); + } + } + + static int getNanoAdjustment(LogRecord record) { + return record.getInstant().getNano() % NANOS_IN_MILLI; + } + static void setNanoAdjustment(LogRecord record, int nanos) { + record.setInstant(Instant.ofEpochSecond(record.getInstant().getEpochSecond(), + (record.getInstant().getNano() / NANOS_IN_MILLI) * NANOS_IN_MILLI + nanos)); + } + + public static void main(String[] args) throws Exception { + + Locale.setDefault(Locale.ENGLISH); + LogRecord record = new LogRecord(Level.INFO, "Java Version: {0}"); + record.setLoggerName("test"); + record.setParameters(new Object[] {System.getProperty("java.version")}); + int nanos = getNanoAdjustment(record); + long millis = record.getMillis(); + // make sure we don't have leading zeros when printing below + // the second precision + if (millis % MILLIS_IN_SECOND < 100) millis = millis + 100; + // make sure we have some nanos + if (nanos % NANOS_IN_MICRO == 0) nanos = nanos + 999; + record.setMillis(millis); + setNanoAdjustment(record, nanos); + final Instant instant = record.getInstant(); + if (nanos < 0) { + throw new RuntimeException("Unexpected negative nano adjustment: " + + getNanoAdjustment(record)); + } + if (nanos >= NANOS_IN_MILLI) { + throw new RuntimeException("Nano adjustment exceeds 1ms: " + + getNanoAdjustment(record)); + } + if (millis != record.getMillis()) { + throw new RuntimeException("Unexpected millis: " + millis + " != " + + record.getMillis()); + } + if (millis != record.getInstant().toEpochMilli()) { + throw new RuntimeException("Unexpected millis: " + + record.getInstant().toEpochMilli()); + } + ZonedDateTime zdt = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault()); + int zdtNanos = zdt.getNano(); + long expectedNanos = (millis % MILLIS_IN_SECOND) * NANOS_IN_MILLI + nanos; + assertEquals(expectedNanos, instant.getNano(), "Instant.getNano()"); + assertEquals(expectedNanos, zdtNanos, "ZonedDateTime.getNano()"); + String match = "."+expectedNanos+" "; + + System.out.println("Testing with default format..."); + + SimpleFormatter formatter = new SimpleFormatter(); + String str = formatter.format(record); + if (str.contains(match)) { + throw new RuntimeException("SimpleFormatter.format()" + + " string contains unexpected nanos: " + + "\n\tdid not expect match for: '" + match + "'" + + "\n\tin: " + str); + } + + System.out.println("Nanos omitted as expected: no '"+match+"' in "+str); + + + System.out.println("Changing format to print nanos..."); + System.setProperty("java.util.logging.SimpleFormatter.format", + "%1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS.%1$tN %1$Tp %2$s%n%4$s: %5$s%6$s%n"); + + SimpleFormatter formatter2 = new SimpleFormatter(); + str = formatter2.format(record); + if (!str.contains(match)) { + throw new RuntimeException("SimpleFormatter.format()" + + " string does not contain expected nanos: " + + "\n\texpected match for: '" + match + "'" + + "\n\tin: " + str); + } + System.out.println("Found expected match for '"+match+"' in "+str); + + + System.out.println("Changing format to omit nanos..."); + System.setProperty("java.util.logging.SimpleFormatter.format", + "%1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS %1$Tp %2$s%n%4$s: %5$s%6$s%n"); + + SimpleFormatter formatter3 = new SimpleFormatter(); + str = formatter3.format(record); + String notMatch = match; + if (str.contains(notMatch)) { + throw new RuntimeException("SimpleFormatter.format()" + + " string contains unexpected nanos: " + + "\n\tdid not expect match for: '" + notMatch + "'" + + "\n\tin: " + str); + } + System.out.println("Nanos omitted as expected: no '"+notMatch+"' in "+str); + + } + +} diff --git a/jdk/test/java/util/logging/HigherResolutionTimeStamps/XmlFormatterNanos.java b/jdk/test/java/util/logging/HigherResolutionTimeStamps/XmlFormatterNanos.java new file mode 100644 index 00000000000..9fce9482361 --- /dev/null +++ b/jdk/test/java/util/logging/HigherResolutionTimeStamps/XmlFormatterNanos.java @@ -0,0 +1,274 @@ +/* + * 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.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.Objects; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.LogManager; +import java.util.logging.LogRecord; +import java.util.logging.XMLFormatter; + +/** + * @test + * @bug 8072645 + * @summary tests that XmlFormatter will print out dates with the new + * nanosecond precision. + * @run main/othervm XmlFormatterNanos + * @author danielfuchs + */ +public class XmlFormatterNanos { + + static final int MILLIS_IN_SECOND = 1000; + static final int NANOS_IN_MILLI = 1000_000; + static final int NANOS_IN_MICRO = 1000; + static final int NANOS_IN_SECOND = 1000_000_000; + + static final boolean verbose = true; + + static final class TestAssertException extends RuntimeException { + TestAssertException(String msg) { super(msg); } + } + + private static void assertEquals(long expected, long received, String msg) { + if (expected != received) { + throw new TestAssertException("Unexpected result for " + msg + + ".\n\texpected: " + expected + + "\n\tactual: " + received); + } else if (verbose) { + System.out.println("Got expected " + msg + ": " + received); + } + } + + private static void assertEquals(Object expected, Object received, String msg) { + if (!Objects.equals(expected, received)) { + throw new TestAssertException("Unexpected result for " + msg + + ".\n\texpected: " + expected + + "\n\tactual: " + received); + } else if (verbose) { + System.out.println("Got expected " + msg + ": " + received); + } + } + + static class CustomXMLFormatter extends XMLFormatter {} + + static class Configuration { + final Properties propertyFile; + private Configuration(Properties properties) { + propertyFile = properties; + } + public Configuration apply() { + try { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + propertyFile.store(bytes, testName()); + ByteArrayInputStream bais = new ByteArrayInputStream(bytes.toByteArray()); + LogManager.getLogManager().readConfiguration(bais); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + return this; + } + + public static String useInstantProperty(Class type) { + return type.getName()+".useInstant"; + } + + public boolean useInstant(XMLFormatter formatter) { + return Boolean.parseBoolean(propertyFile.getProperty( + formatter.getClass().getName()+".useInstant", "true")); + } + + public String testName() { + return propertyFile.getProperty("test.name", "????"); + } + + public static Configuration of(Properties props) { + return new Configuration(props); + } + + public static Configuration apply(Properties props) { + return of(props).apply(); + } + } + + final static List properties; + static { + Properties props1 = new Properties(); + props1.setProperty("test.name", "with XML nano element (default)"); + Properties props2 = new Properties(); + props2.setProperty("test.name", "with XML nano element (standard=true, custom=false)"); + props2.setProperty(Configuration.useInstantProperty(XMLFormatter.class), "true"); + props2.setProperty(Configuration.useInstantProperty(CustomXMLFormatter.class), "false"); + Properties props3 = new Properties(); + props3.setProperty("test.name", "with XML nano element (standard=false, custom=true)"); + props3.setProperty(Configuration.useInstantProperty(XMLFormatter.class), "false"); + props3.setProperty(Configuration.useInstantProperty(CustomXMLFormatter.class), "true"); + + properties = Collections.unmodifiableList(Arrays.asList( + props1, + props2)); + } + + public static void main(String[] args) throws Exception { + Locale.setDefault(Locale.ENGLISH); + properties.stream().forEach(XmlFormatterNanos::test); + } + + static int getNanoAdjustment(LogRecord record) { + return record.getInstant().getNano() % NANOS_IN_MILLI; + } + static void setNanoAdjustment(LogRecord record, int nanos) { + record.setInstant(Instant.ofEpochSecond(record.getInstant().getEpochSecond(), + (record.getInstant().getNano() / NANOS_IN_MILLI) * NANOS_IN_MILLI + nanos)); + } + + public static void test(Properties props) { + Configuration conf = Configuration.apply(props); + + LogRecord record = new LogRecord(Level.INFO, "Test Name: {0}"); + record.setLoggerName("test"); + record.setParameters(new Object[] {conf.testName()}); + int nanos = record.getInstant().getNano() % NANOS_IN_MILLI; + long millis = record.getMillis(); + // make sure we don't have leading zeros when printing below + // the second precision + if (millis % MILLIS_IN_SECOND < 100) millis = millis + 100; + // make sure we some nanos - and make sure we don't have + // trailing zeros + if (nanos % 10 == 0) nanos = nanos + 7; + + record.setMillis(millis); + setNanoAdjustment(record, nanos); + final Instant instant = record.getInstant(); + if (nanos < 0) { + throw new RuntimeException("Unexpected negative nano adjustment: " + + getNanoAdjustment(record)); + } + if (nanos >= NANOS_IN_MILLI) { + throw new RuntimeException("Nano adjustment exceeds 1ms: " + + getNanoAdjustment(record)); + } + if (millis != record.getMillis()) { + throw new RuntimeException("Unexpected millis: " + millis + " != " + + record.getMillis()); + } + if (millis != record.getInstant().toEpochMilli()) { + throw new RuntimeException("Unexpected millis: " + + record.getInstant().toEpochMilli()); + } + long expectedNanos = (millis % MILLIS_IN_SECOND) * NANOS_IN_MILLI + nanos; + assertEquals(expectedNanos, instant.getNano(), "Instant.getNano()"); + + XMLFormatter formatter = new XMLFormatter(); + testMatching(formatter, record, instant, expectedNanos, conf.useInstant(formatter)); + + XMLFormatter custom = new CustomXMLFormatter(); + testMatching(custom, record, instant, expectedNanos, conf.useInstant(custom)); + } + + private static void testMatching(XMLFormatter formatter, + LogRecord record, Instant instant, long expectedNanos, + boolean useInstant) { + + ZonedDateTime zdt = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault()); + int zdtNanos = zdt.getNano(); + assertEquals(expectedNanos, zdtNanos, "ZonedDateTime.getNano()"); + + String str = formatter.format(record); + + String match = "."+expectedNanos; + if (str.contains(match) != useInstant) { + throw new RuntimeException(formatter.getClass().getSimpleName() + + ".format()" + + " string does not contain expected nanos: " + + "\n\texpected match for: '" + match + "'" + + "\n\tin: \n" + str); + } + System.out.println("Found expected match for '"+match+"' in \n"+str); + + match = ""+instant.toEpochMilli()+""; + if (!str.contains(match)) { + throw new RuntimeException(formatter.getClass().getSimpleName() + + ".format()" + + " string does not contain expected millis: " + + "\n\texpected match for: '" + match + "'" + + "\n\tin: \n" + str); + } + System.out.println("Found expected match for '"+match+"' in \n"+str); + + match = ""; + if (str.contains(match) != useInstant) { + throw new RuntimeException(formatter.getClass().getSimpleName() + + ".format()" + + " string " + + (useInstant + ? "does not contain expected nanos: " + : "contains unexpected nanos: ") + + "\n\t" + (useInstant ? "expected" : "unexpected") + + " match for: '" + match + "'" + + "\n\tin: \n" + str); + } + match = ""+getNanoAdjustment(record)+""; + if (str.contains(match) != useInstant) { + throw new RuntimeException(formatter.getClass().getSimpleName() + + ".format()" + + " string " + + (useInstant + ? "does not contain expected nanos: " + : "contains unexpected nanos: ") + + "\n\t" + (useInstant ? "expected" : "unexpected") + + " match for: '" + match + "'" + + "\n\tin: \n" + str); + } + if (useInstant) { + System.out.println("Found expected match for '"+match+"' in \n"+str); + } else { + System.out.println("As expected '"+match+"' is not present in \n"+str); + } + + match = useInstant ? DateTimeFormatter.ISO_INSTANT.format(instant) + : zdt.truncatedTo(ChronoUnit.SECONDS) + .format(DateTimeFormatter.ISO_LOCAL_DATE_TIME); + match = ""+match+""; + if (!str.contains(match)) { + throw new RuntimeException(formatter.getClass().getSimpleName() + + ".format()" + + " string does not contain expected date: " + + "\n\texpected match for: '" + match + "'" + + "\n\tin: \n" + str); + } + System.out.println("Found expected match for '"+match+"' in \n"+str); + + } + +} From c90f8b88398f2a91b6b235a4ef3e59d612af2e93 Mon Sep 17 00:00:00 2001 From: Mark Sheppard Date: Wed, 25 Feb 2015 19:36:29 +0000 Subject: [PATCH 22/29] 8046901: Check jdk/src/solaris/native/sun/nio for Parfait flagged uninitialized memory Reviewed-by: rriggs, alanb --- .../java.base/unix/native/libnio/ch/DatagramChannelImpl.c | 2 +- .../unix/native/libnio/ch/ServerSocketChannelImpl.c | 2 +- jdk/src/jdk.sctp/unix/native/libsctp/SctpNet.c | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/jdk/src/java.base/unix/native/libnio/ch/DatagramChannelImpl.c b/jdk/src/java.base/unix/native/libnio/ch/DatagramChannelImpl.c index f5dd361c4fc..bf7d578f8e1 100644 --- a/jdk/src/java.base/unix/native/libnio/ch/DatagramChannelImpl.c +++ b/jdk/src/java.base/unix/native/libnio/ch/DatagramChannelImpl.c @@ -201,7 +201,7 @@ Java_sun_nio_ch_DatagramChannelImpl_receive0(JNIEnv *env, jobject this, } if (senderAddr == NULL) { jobject isa = NULL; - int port; + int port = 0; jobject ia = NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa, &port); if (ia != NULL) { isa = (*env)->NewObject(env, isa_class, isa_ctorID, ia, port); diff --git a/jdk/src/java.base/unix/native/libnio/ch/ServerSocketChannelImpl.c b/jdk/src/java.base/unix/native/libnio/ch/ServerSocketChannelImpl.c index e96c9b0cc0a..04a400a5daa 100644 --- a/jdk/src/java.base/unix/native/libnio/ch/ServerSocketChannelImpl.c +++ b/jdk/src/java.base/unix/native/libnio/ch/ServerSocketChannelImpl.c @@ -84,7 +84,7 @@ Java_sun_nio_ch_ServerSocketChannelImpl_accept0(JNIEnv *env, jobject this, int alloc_len; jobject remote_ia = 0; jobject isa; - jint remote_port; + jint remote_port = 0; NET_AllocSockaddr(&sa, &alloc_len); if (sa == NULL) { diff --git a/jdk/src/jdk.sctp/unix/native/libsctp/SctpNet.c b/jdk/src/jdk.sctp/unix/native/libsctp/SctpNet.c index 6a5e2cbbb8c..9c3efc0cd93 100644 --- a/jdk/src/jdk.sctp/unix/native/libsctp/SctpNet.c +++ b/jdk/src/jdk.sctp/unix/native/libsctp/SctpNet.c @@ -431,7 +431,7 @@ jobjectArray getRemoteAddresses paddr = addr_buf; for (i=0; i Date: Wed, 25 Feb 2015 13:04:31 -0800 Subject: [PATCH 23/29] 8073893: Enable charsets build system to configure euc_tw into java.base module/sun.nio.cs To enable charsets build system to configure euc_tw into java.base module/sun.nio.cs Reviewed-by: alanb, mchung --- jdk/make/data/charsetmapping/charsets | 16 +++++++++++- jdk/make/data/charsetmapping/stdcs-solaris | 1 + jdk/make/gensrc/Gensrc-jdk.charsets.gmk | 4 ++- jdk/make/gensrc/GensrcCharsetMapping.gmk | 5 +++- .../build/tools/charsetmapping/Charset.java | 1 + .../build/tools/charsetmapping/EUC_TW.java | 6 ++--- .../build/tools/charsetmapping/HKSCS.java | 9 ++++--- .../build/tools/charsetmapping/Main.java | 26 +++++++++++++++---- .../build/tools/charsetmapping/SPI.java | 9 ++++--- .../classes/sun/awt/motif/X11CNS11643.java | 3 ++- .../ext/{EUC_TW.java => EUC_TW.java.template} | 4 +-- .../nio/cs/ext/ExtendedCharsets.java.template | 10 ------- .../sun/nio/cs/ext/ISO2022_CN_CNS.java | 1 + jdk/test/sun/nio/cs/X11CNS11643.java | 3 ++- 14 files changed, 66 insertions(+), 32 deletions(-) rename jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/{EUC_TW.java => EUC_TW.java.template} (99%) diff --git a/jdk/make/data/charsetmapping/charsets b/jdk/make/data/charsetmapping/charsets index 682a14ca46c..09d06c5a335 100644 --- a/jdk/make/data/charsetmapping/charsets +++ b/jdk/make/data/charsetmapping/charsets @@ -503,7 +503,7 @@ charset x-windows-874 MS874 charset x-EUC-TW EUC_TW package sun.nio.cs.ext - type source + type template alias euc_tw # JDK historical alias euctw alias cns11643 @@ -1816,3 +1816,17 @@ charset x-JIS0212_MS5022X JIS_X_0212_MS5022X ascii false minmax 0x21 0x7e 0x21 0x7e internal true # "internal implementation + +######################################################## +# +# platform specific charsets, to be registered into spi +## +######################################################## + +charset x-COMPOUND_TEXT COMPOUND_TEXT + package sun.nio.cs.ext + type source + os unix + alias COMPOUND_TEXT # JDK historical + alias x11-compound_text + alias x-compound-text diff --git a/jdk/make/data/charsetmapping/stdcs-solaris b/jdk/make/data/charsetmapping/stdcs-solaris index 6e57033b3c7..9ec5ff53838 100644 --- a/jdk/make/data/charsetmapping/stdcs-solaris +++ b/jdk/make/data/charsetmapping/stdcs-solaris @@ -9,6 +9,7 @@ EUC_KR EUC_JP EUC_JP_LINUX EUC_JP_Open +EUC_TW GBK ISO_8859_11 ISO_8859_3 diff --git a/jdk/make/gensrc/Gensrc-jdk.charsets.gmk b/jdk/make/gensrc/Gensrc-jdk.charsets.gmk index 85d67f34c71..fc6c481f523 100644 --- a/jdk/make/gensrc/Gensrc-jdk.charsets.gmk +++ b/jdk/make/gensrc/Gensrc-jdk.charsets.gmk @@ -50,7 +50,9 @@ $(CHARSET_DONE_CS)-extcs: $(CHARSET_DATA_DIR)/charsets \ $(TOOL_CHARSETMAPPING) $(CHARSET_DATA_DIR) $(CHARSET_GENSRC_JAVA_DIR_CS) \ extcs charsets $(CHARSET_STANDARD_OS) \ $(CHARSET_EXTENDED_JAVA_TEMPLATES) \ - $(CHARSET_EXTENDED_JAVA_DIR) $(LOG_INFO) + $(CHARSET_EXTENDED_JAVA_DIR) \ + $(CHARSET_COPYRIGHT_HEADER) \ + $(LOG_INFO) $(TOUCH) '$@' $(CHARSET_DONE_CS)-hkscs: $(CHARSET_COPYRIGHT_HEADER)/HKSCS.java \ diff --git a/jdk/make/gensrc/GensrcCharsetMapping.gmk b/jdk/make/gensrc/GensrcCharsetMapping.gmk index e0243a95dcf..0218d4a1039 100644 --- a/jdk/make/gensrc/GensrcCharsetMapping.gmk +++ b/jdk/make/gensrc/GensrcCharsetMapping.gmk @@ -32,6 +32,7 @@ CHARSET_DATA_DIR := $(JDK_TOPDIR)/make/data/charsetmapping CHARSET_EXTSRC_DIR := $(JDK_TOPDIR)/src/jdk.charsets/share/classes/sun/nio/cs/ext CHARSET_GENSRC_JAVA_DIR_BASE := $(SUPPORT_OUTPUTDIR)/gensrc/java.base/sun/nio/cs CHARSET_DONE_BASE := $(CHARSET_GENSRC_JAVA_DIR_BASE)/_the.charsetmapping +CHARSET_COPYRIGHT_HEADER := $(JDK_TOPDIR)/make/src/classes/build/tools/charsetmapping CHARSET_TEMPLATES := \ $(CHARSET_DATA_DIR)/SingleByte-X.java.template \ $(CHARSET_DATA_DIR)/DoubleByte-X.java.template @@ -46,7 +47,9 @@ $(CHARSET_DONE_BASE)-stdcs: $(CHARSET_DATA_DIR)/charsets \ $(MKDIR) -p $(@D) $(TOOL_CHARSETMAPPING) $(CHARSET_DATA_DIR) $(CHARSET_GENSRC_JAVA_DIR_BASE) \ stdcs charsets $(CHARSET_STANDARD_OS) \ - $(CHARSET_STANDARD_JAVA_TEMPLATES) $(CHARSET_EXTSRC_DIR) $(LOG_INFO) + $(CHARSET_STANDARD_JAVA_TEMPLATES) $(CHARSET_EXTSRC_DIR) \ + $(CHARSET_COPYRIGHT_HEADER) \ + $(LOG_INFO) $(TOUCH) '$@' GENSRC_JAVA_BASE += $(CHARSET_DONE_BASE)-stdcs diff --git a/jdk/make/src/classes/build/tools/charsetmapping/Charset.java b/jdk/make/src/classes/build/tools/charsetmapping/Charset.java index 94d61c35f0d..779382a377d 100644 --- a/jdk/make/src/classes/build/tools/charsetmapping/Charset.java +++ b/jdk/make/src/classes/build/tools/charsetmapping/Charset.java @@ -31,6 +31,7 @@ class Charset { String csName; String hisName; String type; + String os; boolean isASCII; int b1Min; int b1Max; diff --git a/jdk/make/src/classes/build/tools/charsetmapping/EUC_TW.java b/jdk/make/src/classes/build/tools/charsetmapping/EUC_TW.java index 5ef0e679c60..e713b0a5e5c 100644 --- a/jdk/make/src/classes/build/tools/charsetmapping/EUC_TW.java +++ b/jdk/make/src/classes/build/tools/charsetmapping/EUC_TW.java @@ -80,12 +80,12 @@ public class EUC_TW { private static Pattern euctw = Pattern.compile("(?:8ea)?(\\p{XDigit}++)\\s++(\\p{XDigit}++)?\\s*+.*"); - static void genClass(String args[]) throws Exception + static void genClass(String pkg, String args[]) throws Exception { InputStream is = new FileInputStream(new File(args[0], "euc_tw.map")); PrintStream ps = new PrintStream(new File(args[1], "EUC_TWMapping.java"), "ISO-8859-1"); - String copyright = getCopyright(new File(args[3])); + String copyright = getCopyright(new File(args[7], "EUC_TW.java")); // ranges of byte1 and byte2, something should come from a "config" file @@ -128,7 +128,7 @@ public class EUC_TW { out.format(copyright); out.format("%n// -- This file was mechanically generated: Do not edit! -- //%n"); - out.format("package sun.nio.cs.ext;%n%n"); + out.format("package %s;%n%n", pkg); out.format("class EUC_TWMapping {%n%n"); // boundaries diff --git a/jdk/make/src/classes/build/tools/charsetmapping/HKSCS.java b/jdk/make/src/classes/build/tools/charsetmapping/HKSCS.java index 18c0a24ad7b..0fe4e295df8 100644 --- a/jdk/make/src/classes/build/tools/charsetmapping/HKSCS.java +++ b/jdk/make/src/classes/build/tools/charsetmapping/HKSCS.java @@ -42,7 +42,7 @@ public class HKSCS { private static Pattern hkscs = Pattern.compile("(?:0x)?+(\\p{XDigit}++)\\s++(?:0x|U\\+)?+(\\p{XDigit}++)?\\s*+(?:0x|U\\+)?(\\p{XDigit}++)?\\s*+.*"); - static void genClass2008(String srcDir, String dstDir, String pkgName) + static void genClass2008(String srcDir, String dstDir, String pkgName, File copyright) throws Exception { // hkscs2008 @@ -53,10 +53,11 @@ public class HKSCS { pkgName, "HKSCSMapping", true, - ""); + getCopyright(copyright)); + } - static void genClassXP(String srcDir, String dstDir, String pkgName) + static void genClassXP(String srcDir, String dstDir, String pkgName, File copyright) throws Exception { genClass0(new FileInputStream(new File(srcDir, "HKSCS_XP.map")), @@ -66,7 +67,7 @@ public class HKSCS { pkgName, "HKSCS_XPMapping", false, - ""); + getCopyright(copyright)); } static void genClass2001(String args[]) throws Exception { diff --git a/jdk/make/src/classes/build/tools/charsetmapping/Main.java b/jdk/make/src/classes/build/tools/charsetmapping/Main.java index b129288ea26..cd9229ef02e 100644 --- a/jdk/make/src/classes/build/tools/charsetmapping/Main.java +++ b/jdk/make/src/classes/build/tools/charsetmapping/Main.java @@ -41,6 +41,7 @@ public class Main { int OS = 4; int TEMPLATE = 5; int EXT_SRC = 6; + int COPYRIGHT_SRC = 7; if (args.length < 3 ) { System.out.println("Usage: java -jar charsetmapping.jar src dst spiType charsets os [template]"); @@ -54,6 +55,7 @@ public class Main { String[] osStdcs = getOSStdCSList(new File(args[SRC_DIR], args[OS])); boolean hasBig5_HKSCS = false; boolean hasMS950_HKSCS_XP = false; + boolean hasEUC_TW = false; for (String name : osStdcs) { Charset cs = charsets.get(name); if (cs != null) { @@ -63,6 +65,8 @@ public class Main { hasBig5_HKSCS = true; } else if (name.equals("MS950_HKSCS_XP")) { hasMS950_HKSCS_XP = true; + } else if (name.equals("EUC_TW")) { + hasEUC_TW = true; } } for (Charset cs : charsets.values()) { @@ -89,19 +93,28 @@ public class Main { } } // provider StandardCharsets.java / ExtendedCharsets.java - SPI.genClass(args[TYPE], charsets, args[SRC_DIR], args[DST_DIR], args[TEMPLATE]); + SPI.genClass(args[TYPE], charsets, + args[SRC_DIR], args[DST_DIR], + args[TEMPLATE], + args[OS].endsWith("windows") ? "windows" : "unix"); // HKSCSMapping2008/XP.java goes together with Big5/MS950XP_HKSCS if (isStandard && hasBig5_HKSCS || isExtended && !hasBig5_HKSCS) { HKSCS.genClass2008(args[SRC_DIR], args[DST_DIR], - isStandard ? "sun.nio.cs" : "sun.nio.cs.ext"); + isStandard ? "sun.nio.cs" : "sun.nio.cs.ext", + new File(args[COPYRIGHT_SRC], "HKSCS.java")); } if (isStandard && hasMS950_HKSCS_XP || isExtended && !hasMS950_HKSCS_XP) { HKSCS.genClassXP(args[SRC_DIR], args[DST_DIR], - isStandard ? "sun.nio.cs" : "sun.nio.cs.ext"); + isStandard ? "sun.nio.cs" : "sun.nio.cs.ext", + new File(args[COPYRIGHT_SRC], "HKSCS.java")); + } + if (isStandard && hasEUC_TW) { + EUC_TW.genClass("sun.nio.cs", args); + } + if (!isStandard && !hasEUC_TW) { + EUC_TW.genClass("sun.nio.cs.ext", args); } - } else if ("euctw".equals(args[TYPE])) { - EUC_TW.genClass(args); } else if ("sjis0213".equals(args[TYPE])) { JIS0213.genClass(args); } else if ("hkscs".equals(args[TYPE])) { @@ -157,6 +170,9 @@ public class Main { case "type": cs.type = tokens[2]; break; + case "os": + cs.os = tokens[2]; + break; case "hisname": cs.hisName = tokens[2]; break; diff --git a/jdk/make/src/classes/build/tools/charsetmapping/SPI.java b/jdk/make/src/classes/build/tools/charsetmapping/SPI.java index e0e2458bc40..7e35c57cc4e 100644 --- a/jdk/make/src/classes/build/tools/charsetmapping/SPI.java +++ b/jdk/make/src/classes/build/tools/charsetmapping/SPI.java @@ -33,8 +33,10 @@ import java.util.Scanner; public class SPI { - public static void genClass(String type, LinkedHashMap charsets, - String srcDir, String dstDir, String template) + public static void genClass(String type, + LinkedHashMap charsets, + String srcDir, String dstDir, String template, + String os) throws Exception { try (Scanner s = new Scanner(new File(template)); @@ -50,7 +52,8 @@ public class SPI { charsets.values() .stream() .filter(cs -> cs.pkgName.equals("sun.nio.cs.ext") && - !cs.isInternal) + !cs.isInternal && + (cs.os == null || cs.os.equals(os))) .forEach( cs -> { out.printf(" charset(\"%s\", \"%s\",%n", cs.csName, cs.clzName); out.printf(" new String[] {%n"); diff --git a/jdk/src/java.desktop/unix/classes/sun/awt/motif/X11CNS11643.java b/jdk/src/java.desktop/unix/classes/sun/awt/motif/X11CNS11643.java index 1d91a872f52..6aff454ee56 100644 --- a/jdk/src/java.desktop/unix/classes/sun/awt/motif/X11CNS11643.java +++ b/jdk/src/java.desktop/unix/classes/sun/awt/motif/X11CNS11643.java @@ -28,7 +28,8 @@ package sun.awt.motif; import java.nio.CharBuffer; import java.nio.ByteBuffer; import java.nio.charset.*; -import sun.nio.cs.ext.EUC_TW; +import sun.nio.cs.*; +import sun.nio.cs.ext.*; public abstract class X11CNS11643 extends Charset { private final int plane; diff --git a/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_TW.java b/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_TW.java.template similarity index 99% rename from jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_TW.java rename to jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_TW.java.template index d922eff81c9..14620a2a40b 100644 --- a/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_TW.java +++ b/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_TW.java.template @@ -23,7 +23,7 @@ * questions. */ -package sun.nio.cs.ext; +package $PACKAGE$; import java.io.*; import java.nio.CharBuffer; @@ -79,7 +79,7 @@ public class EUC_TW extends Charset implements HistoricallyNamedCharset */ public EUC_TW() { - super("x-EUC-TW", ExtendedCharsets.aliasesFor("x-EUC-TW")); + super("x-EUC-TW", $ALIASES$); } public String historicalName() { diff --git a/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/ExtendedCharsets.java.template b/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/ExtendedCharsets.java.template index a37d43b0787..a25018a1235 100644 --- a/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/ExtendedCharsets.java.template +++ b/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/ExtendedCharsets.java.template @@ -222,16 +222,6 @@ public class ExtendedCharsets extends AbstractCharsetProvider { } } - String osName = getProperty("os.name"); - if ("SunOS".equals(osName) || "Linux".equals(osName) || "AIX".equals(osName) - || osName.contains("OS X")) { - charset("x-COMPOUND_TEXT", "COMPOUND_TEXT", - new String[] { - "COMPOUND_TEXT", // JDK historical - "x11-compound_text", - "x-compound-text" - }); - } initialized = true; } diff --git a/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_CN_CNS.java b/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_CN_CNS.java index 9523cb3e31e..f9fe0417af0 100644 --- a/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_CN_CNS.java +++ b/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_CN_CNS.java @@ -35,6 +35,7 @@ import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; import java.nio.charset.CoderResult; import sun.nio.cs.HistoricallyNamedCharset; +import sun.nio.cs.*; public class ISO2022_CN_CNS extends ISO2022 implements HistoricallyNamedCharset { diff --git a/jdk/test/sun/nio/cs/X11CNS11643.java b/jdk/test/sun/nio/cs/X11CNS11643.java index 550be6b4c8b..399f3b70e15 100644 --- a/jdk/test/sun/nio/cs/X11CNS11643.java +++ b/jdk/test/sun/nio/cs/X11CNS11643.java @@ -24,7 +24,8 @@ import java.nio.CharBuffer; import java.nio.ByteBuffer; import java.nio.charset.*; -import sun.nio.cs.ext.EUC_TW; +import sun.nio.cs.*; +import sun.nio.cs.ext.*; public abstract class X11CNS11643 extends Charset { private final int plane; From c12ac1b4cc70c56bdd5a2a0f6162e755ed9b74a9 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Thu, 26 Feb 2015 08:08:52 +0800 Subject: [PATCH 24/29] 8073853: KeyToolTest.java has too many too long lines Reviewed-by: mullan --- .../security/tools/keytool/KeyToolTest.java | 1148 ++++++++++++----- 1 file changed, 809 insertions(+), 339 deletions(-) diff --git a/jdk/test/sun/security/tools/keytool/KeyToolTest.java b/jdk/test/sun/security/tools/keytool/KeyToolTest.java index bedf9824c91..9c98341ca50 100644 --- a/jdk/test/sun/security/tools/keytool/KeyToolTest.java +++ b/jdk/test/sun/security/tools/keytool/KeyToolTest.java @@ -42,7 +42,8 @@ * echo | java -Dsolaris KeyToolTest * * ATTENTION: - * Exception in thread "main" java.security.ProviderException: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_KEY_SIZE_RANGE + * Exception in thread "main" java.security.ProviderException: + * sun.security.pkcs11.wrapper.PKCS11Exception: CKR_KEY_SIZE_RANGE * at sun.security.pkcs11.P11Signature.engineSign(P11Signature.java:420) * ... * Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_KEY_SIZE_RANGE @@ -78,15 +79,26 @@ public class KeyToolTest { System.getProperty("debug") != null; static final String NSS_P11_ARG = - "-keystore NONE -storetype PKCS11 -providerName SunPKCS11-nss -providerClass sun.security.pkcs11.SunPKCS11 -providerArg p11-nss.txt "; + "-keystore NONE -storetype PKCS11 -providerName SunPKCS11-nss " + + "-providerClass sun.security.pkcs11.SunPKCS11 " + + "-providerArg p11-nss.txt "; static final String NSS_SRC_P11_ARG = - "-srckeystore NONE -srcstoretype PKCS11 -srcproviderName SunPKCS11-nss -providerClass sun.security.pkcs11.SunPKCS11 -providerArg p11-nss.txt "; + "-srckeystore NONE -srcstoretype PKCS11 " + + "-srcproviderName SunPKCS11-nss " + + "-providerClass sun.security.pkcs11.SunPKCS11 " + + "-providerArg p11-nss.txt "; static final String NZZ_P11_ARG = - "-keystore NONE -storetype PKCS11 -providerName SunPKCS11-nzz -providerClass sun.security.pkcs11.SunPKCS11 -providerArg p11-nzz.txt "; + "-keystore NONE -storetype PKCS11 -providerName SunPKCS11-nzz " + + "-providerClass sun.security.pkcs11.SunPKCS11 " + + "-providerArg p11-nzz.txt "; static final String NZZ_SRC_P11_ARG = - "-srckeystore NONE -srcstoretype PKCS11 -srcproviderName SunPKCS11-nzz -providerClass sun.security.pkcs11.SunPKCS11 -providerArg p11-nzz.txt "; + "-srckeystore NONE -srcstoretype PKCS11 " + + "-srcproviderName SunPKCS11-nzz " + + "-providerClass sun.security.pkcs11.SunPKCS11 " + + "-providerArg p11-nzz.txt "; static final String SUN_P11_ARG = "-keystore NONE -storetype PKCS11 "; - static final String SUN_SRC_P11_ARG = "-srckeystore NONE -srcstoretype PKCS11 "; + static final String SUN_SRC_P11_ARG = + "-srckeystore NONE -srcstoretype PKCS11 "; String p11Arg, srcP11Arg; @@ -328,15 +340,22 @@ public class KeyToolTest { // name changes: genkeypair, importcert, exportcert remove("x.jks"); remove("x.jks.p1.cert"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -alias p1 -dname CN=olala"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -exportcert -alias p1 -file x.jks.p1.cert"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -alias p1 -dname CN=olala"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-exportcert -alias p1 -file x.jks.p1.cert"); ks = loadStore("x.jks", "changeit", "JKS"); assertTrue(ks.getKey("p1", "changeit".toCharArray()) != null, "key not DSA"); assertTrue(new File("x.jks.p1.cert").exists(), "p1 export err"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -delete -alias p1"); - testOK("y\n", "-keystore x.jks -storetype JKS -storepass changeit -importcert -alias c1 -file x.jks.p1.cert"); // importcert, prompt for Yes/No - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -importcert -alias c2 -file x.jks.p1.cert -noprompt"); // importcert, -noprompt + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-delete -alias p1"); + // importcert, prompt for Yes/No + testOK("y\n", "-keystore x.jks -storetype JKS -storepass changeit " + + "-importcert -alias c1 -file x.jks.p1.cert"); + // importcert, -noprompt + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-importcert -alias c2 -file x.jks.p1.cert -noprompt"); ks = loadStore("x.jks", "changeit", "JKS"); assertTrue(ks.getCertificate("c1") != null, "import c1 err"); @@ -346,10 +365,15 @@ public class KeyToolTest { assertTrue(certImpl.getVersion() == 3, "Version is not 3"); // changealias and keyclone - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -alias p1 -dname CN=olala"); - testOK("changeit\n", "-keystore x.jks -storetype JKS -changealias -alias p1 -destalias p11"); - testOK("changeit\n", "-keystore x.jks -storetype JKS -changealias -alias c1 -destalias c11"); - testOK("changeit\n\n", "-keystore x.jks -storetype JKS -keyclone -alias p11 -destalias p111"); // press ENTER when prompt for p111's keypass + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -alias p1 -dname CN=olala"); + testOK("changeit\n", "-keystore x.jks -storetype JKS " + + "-changealias -alias p1 -destalias p11"); + testOK("changeit\n", "-keystore x.jks -storetype JKS " + + "-changealias -alias c1 -destalias c11"); + // press ENTER when prompt for p111's keypass + testOK("changeit\n\n", "-keystore x.jks -storetype JKS " + + "-keyclone -alias p11 -destalias p111"); ks = loadStore("x.jks", "changeit", "JKS"); assertTrue(!ks.containsAlias("p1"), "there is no p1"); assertTrue(!ks.containsAlias("c1"), "there is no c1"); @@ -359,148 +383,283 @@ public class KeyToolTest { // genSecKey remove("x.jceks"); - testOK("changeit\nchangeit\n\n", "-keystore x.jceks -storetype JCEKS -genseckey -alias s1"); // DES, no need keysize - testFail("changeit\n\n", "-keystore x.jceks -storetype JCEKS -genseckey -alias s11 -keysize 128"); // DES, keysize cannot be 128 - testOK("changeit\n\n", "-keystore x.jceks -storetype JCEKS -genseckey -keyalg DESede -alias s2"); // DESede. no need keysize - testFail("changeit\n\n", "-keystore x.jceks -storetype AES -genseckey -keyalg Rijndael -alias s3"); // AES, need keysize - testOK("changeit\n\n", "-keystore x.jceks -storetype JCEKS -genseckey -keyalg AES -alias s3 -keysize 128"); - // about keypass - testOK("\n", "-keystore x.jceks -storetype JCEKS -storepass changeit -genseckey -alias s4"); // can accept storepass - testOK("keypass\nkeypass\n", "-keystore x.jceks -storetype JCEKS -storepass changeit -genseckey -alias s5"); // or a new one - testOK("bad\n\bad\nkeypass\nkeypass\n", "-keystore x.jceks -storetype JCEKS -storepass changeit -genseckey -alias s6"); // keypass must be valid (prompt 3 times) - testFail("bad\n\bad\nbad\n", "-keystore x.jceks -storetype JCEKS -storepass changeit -genseckey -alias s7"); // keypass must be valid (prompt 3 times) - testFail("bad\n\bad\nbad\nkeypass\n", "-keystore x.jceks -storetype JCEKS -storepass changeit -genseckey -alias s7"); // keypass must be valid (prompt 3 times) + // DES, no need keysize + testOK("changeit\nchangeit\n\n", "-keystore x.jceks -storetype JCEKS " + + "-genseckey -alias s1"); + // DES, keysize cannot be 128 + testFail("changeit\n\n", "-keystore x.jceks -storetype JCEKS " + + "-genseckey -alias s11 -keysize 128"); + // DESede. no need keysize + testOK("changeit\n\n", "-keystore x.jceks -storetype JCEKS " + + "-genseckey -keyalg DESede -alias s2"); + // AES, need keysize + testFail("changeit\n\n", "-keystore x.jceks -storetype AES " + + "-genseckey -keyalg Rijndael -alias s3"); + testOK("changeit\n\n", "-keystore x.jceks -storetype JCEKS " + + "-genseckey -keyalg AES -alias s3 -keysize 128"); + // about keypass + // can accept storepass + testOK("\n", "-keystore x.jceks -storetype JCEKS -storepass changeit " + + "-genseckey -alias s4"); + // or a new one + testOK("keypass\nkeypass\n", "-keystore x.jceks -storetype JCEKS " + + "-storepass changeit -genseckey -alias s5"); + // keypass must be valid (prompt 3 times) + testOK("bad\n\bad\nkeypass\nkeypass\n", "-keystore x.jceks " + + "-storetype JCEKS -storepass changeit -genseckey -alias s6"); + // keypass must be valid (prompt 3 times) + testFail("bad\n\bad\nbad\n", "-keystore x.jceks -storetype JCEKS " + + "-storepass changeit -genseckey -alias s7"); + // keypass must be valid (prompt 3 times) + testFail("bad\n\bad\nbad\nkeypass\n", "-keystore x.jceks " + + "-storetype JCEKS -storepass changeit -genseckey -alias s7"); ks = loadStore("x.jceks", "changeit", "JCEKS"); - assertTrue(ks.getKey("s1", "changeit".toCharArray()).getAlgorithm().equalsIgnoreCase("DES"), "s1 is DES"); - assertTrue(ks.getKey("s1", "changeit".toCharArray()).getEncoded().length == 8, "DES is 56"); - assertTrue(ks.getKey("s2", "changeit".toCharArray()).getEncoded().length == 24, "DESede is 168"); - assertTrue(ks.getKey("s2", "changeit".toCharArray()).getAlgorithm().equalsIgnoreCase("DESede"), "s2 is DESede"); - assertTrue(ks.getKey("s3", "changeit".toCharArray()).getAlgorithm().equalsIgnoreCase("AES"), "s3 is AES"); - assertTrue(ks.getKey("s4", "changeit".toCharArray()).getAlgorithm().equalsIgnoreCase("DES"), "s4 is DES"); - assertTrue(ks.getKey("s5", "keypass".toCharArray()).getAlgorithm().equalsIgnoreCase("DES"), "s5 is DES"); - assertTrue(ks.getKey("s6", "keypass".toCharArray()).getAlgorithm().equalsIgnoreCase("DES"), "s6 is DES"); + assertTrue(ks.getKey("s1", "changeit".toCharArray()) + .getAlgorithm().equalsIgnoreCase("DES"), "s1 is DES"); + assertTrue(ks.getKey("s1", "changeit".toCharArray()) + .getEncoded().length == 8, "DES is 56"); + assertTrue(ks.getKey("s2", "changeit".toCharArray()) + .getEncoded().length == 24, "DESede is 168"); + assertTrue(ks.getKey("s2", "changeit".toCharArray()) + .getAlgorithm().equalsIgnoreCase("DESede"), "s2 is DESede"); + assertTrue(ks.getKey("s3", "changeit".toCharArray()) + .getAlgorithm().equalsIgnoreCase("AES"), "s3 is AES"); + assertTrue(ks.getKey("s4", "changeit".toCharArray()) + .getAlgorithm().equalsIgnoreCase("DES"), "s4 is DES"); + assertTrue(ks.getKey("s5", "keypass".toCharArray()) + .getAlgorithm().equalsIgnoreCase("DES"), "s5 is DES"); + assertTrue(ks.getKey("s6", "keypass".toCharArray()) + .getAlgorithm().equalsIgnoreCase("DES"), "s6 is DES"); assertTrue(!ks.containsAlias("s7"), "s7 not created"); // maybe we needn't test this, one day JKS will support SecretKey - //testFail("changeit\nchangeit\n", "-keystore x.jks -storetype JKS -genseckey -keyalg AES -alias s3 -keysize 128"); + //testFail("changeit\nchangeit\n", "-keystore x.jks -storetype JKS " + + // "-genseckey -keyalg AES -alias s3 -keysize 128"); // importKeyStore remove("x.jks"); remove("x.jceks"); - testOK("changeit\nchangeit\n\n", "-keystore x.jceks -storetype JCEKS -genkeypair -alias p1 -dname CN=Olala"); // create 2 entries... - testOK("", "-keystore x.jceks -storetype JCEKS -storepass changeit -importcert -alias c1 -file x.jks.p1.cert -noprompt"); // ... + // create 2 entries... + testOK("changeit\nchangeit\n\n", "-keystore x.jceks -storetype JCEKS " + + "-genkeypair -alias p1 -dname CN=Olala"); + testOK("", "-keystore x.jceks -storetype JCEKS -storepass changeit " + + "-importcert -alias c1 -file x.jks.p1.cert -noprompt"); ks = loadStore("x.jceks", "changeit", "JCEKS"); assertTrue(ks.size() == 2, "2 entries in JCEKS"); - // import, shouldn't mention destalias/srckeypass/destkeypass if srcalias is no given - testFail("changeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -destalias pp"); - testFail("changeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srckeypass changeit"); - testFail("changeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -destkeypass changeit"); + // import, shouldn't mention destalias/srckeypass/destkeypass + // if srcalias is no given + testFail("changeit\nchangeit\n", "-importkeystore " + + "-srckeystore x.jceks -srcstoretype JCEKS " + + "-destkeystore x.jks -deststoretype JKS -destalias pp"); + testFail("changeit\nchangeit\n", "-importkeystore " + + "-srckeystore x.jceks -srcstoretype JCEKS " + + "-destkeystore x.jks -deststoretype JKS -srckeypass changeit"); + testFail("changeit\nchangeit\n", "-importkeystore " + + "-srckeystore x.jceks -srcstoretype JCEKS " + + "-destkeystore x.jks -deststoretype JKS -destkeypass changeit"); // normal import - testOK("changeit\nchangeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS"); + testOK("changeit\nchangeit\nchangeit\n", "-importkeystore " + + "-srckeystore x.jceks -srcstoretype JCEKS " + + "-destkeystore x.jks -deststoretype JKS"); ks = loadStore("x.jks", "changeit", "JKS"); assertTrue(ks.size() == 2, "2 entries in JKS"); // import again, type yes to overwrite old entries - testOK("changeit\nchangeit\ny\ny\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS"); + testOK("changeit\nchangeit\ny\ny\n", "-importkeystore " + + "-srckeystore x.jceks -srcstoretype JCEKS " + + "-destkeystore x.jks -deststoretype JKS"); ks = loadStore("x.jks", "changeit", "JKS"); // import again, specify -nopromt - testOK("changeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -noprompt"); + testOK("changeit\nchangeit\n", "-importkeystore " + + "-srckeystore x.jceks -srcstoretype JCEKS " + + "-destkeystore x.jks -deststoretype JKS -noprompt"); assertTrue(err.indexOf("Warning") != -1, "noprompt will warn"); ks = loadStore("x.jks", "changeit", "JKS"); assertTrue(ks.size() == 2, "2 entries in JKS"); // import again, type into new aliases when prompted - testOK("changeit\nchangeit\n\ns1\n\ns2\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS"); + testOK("changeit\nchangeit\n\ns1\n\ns2\n", "-importkeystore " + + "-srckeystore x.jceks -srcstoretype JCEKS " + + "-destkeystore x.jks -deststoretype JKS"); ks = loadStore("x.jks", "changeit", "JKS"); assertTrue(ks.size() == 4, "4 entries in JKS"); // importkeystore single + // normal remove("x.jks"); - testOK("changeit\nchangeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias p1"); // normal + testOK("changeit\nchangeit\nchangeit\n", "-importkeystore " + + "-srckeystore x.jceks -srcstoretype JCEKS " + + "-destkeystore x.jks -deststoretype JKS -srcalias p1"); ks = loadStore("x.jks", "changeit", "JKS"); assertTrue(ks.size() == 1, "1 entries in JKS"); - testOK("changeit\nchangeit\ny\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias p1"); // overwrite + // overwrite + testOK("changeit\nchangeit\ny\n", "-importkeystore " + + "-srckeystore x.jceks -srcstoretype JCEKS " + + "-destkeystore x.jks -deststoretype JKS -srcalias p1"); ks = loadStore("x.jks", "changeit", "JKS"); assertTrue(ks.size() == 1, "1 entries in JKS"); - testOK("changeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias p1 -noprompt"); // noprompt + // noprompt + testOK("changeit\nchangeit\n", "-importkeystore " + + "-srckeystore x.jceks -srcstoretype JCEKS " + + "-destkeystore x.jks -deststoretype JKS " + + "-srcalias p1 -noprompt"); ks = loadStore("x.jks", "changeit", "JKS"); assertTrue(ks.size() == 1, "1 entries in JKS"); - testOK("changeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias p1 -destalias p2"); // rename + // rename + testOK("changeit\nchangeit\n", "-importkeystore " + + "-srckeystore x.jceks -srcstoretype JCEKS " + + "-destkeystore x.jks -deststoretype JKS " + + "-srcalias p1 -destalias p2"); ks = loadStore("x.jks", "changeit", "JKS"); assertTrue(ks.size() == 2, "2 entries in JKS"); - testOK("changeit\nchangeit\n\nnewalias\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias p1"); // another rename + // another rename + testOK("changeit\nchangeit\n\nnewalias\n", "-importkeystore " + + "-srckeystore x.jceks -srcstoretype JCEKS " + + "-destkeystore x.jks -deststoretype JKS -srcalias p1"); ks = loadStore("x.jks", "changeit", "JKS"); assertTrue(ks.size() == 3, "3 entries in JKS"); // importkeystore single, different keypass remove("x.jks"); - testOK("changeit\nkeypass\nkeypass\n", "-keystore x.jceks -storetype JCEKS -genkeypair -alias p2 -dname CN=Olala"); // generate entry with different keypass - testOK("changeit\nchangeit\nchangeit\nkeypass\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias p2"); // prompt + // generate entry with different keypass + testOK("changeit\nkeypass\nkeypass\n", "-keystore x.jceks " + + "-storetype JCEKS -genkeypair -alias p2 -dname CN=Olala"); + // prompt + testOK("changeit\nchangeit\nchangeit\nkeypass\n", "-importkeystore " + + "-srckeystore x.jceks -srcstoretype JCEKS " + + "-destkeystore x.jks -deststoretype JKS -srcalias p2"); ks = loadStore("x.jks", "changeit", "JKS"); assertTrue(ks.size() == 1, "1 entries in JKS"); - testOK("changeit\nchangeit\nkeypass\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias p2 -destalias p3 -destkeypass keypass2"); // diff destkeypass + // diff destkeypass + testOK("changeit\nchangeit\nkeypass\n", "-importkeystore " + + "-srckeystore x.jceks -srcstoretype JCEKS " + + "-destkeystore x.jks -deststoretype JKS " + + "-srcalias p2 -destalias p3 -destkeypass keypass2"); ks = loadStore("x.jks", "changeit", "JKS"); assertTrue(ks.size() == 2, "2 entries in JKS"); - assertTrue(ks.getKey("p2", "keypass".toCharArray()) != null, "p2 has old password"); - assertTrue(ks.getKey("p3", "keypass2".toCharArray()) != null, "p3 has new password"); + assertTrue(ks.getKey("p2", "keypass".toCharArray()) != null, + "p2 has old password"); + assertTrue(ks.getKey("p3", "keypass2".toCharArray()) != null, + "p3 has new password"); // importkeystore single, cert remove("x.jks"); - testOK("changeit\nchangeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias c1"); // normal - testOK("changeit\n\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias c1 -destalias c2"); // in fact srcstorepass can be ignored + // normal + testOK("changeit\nchangeit\nchangeit\n", "-importkeystore " + + "-srckeystore x.jceks -srcstoretype JCEKS " + + "-destkeystore x.jks -deststoretype JKS -srcalias c1"); + // in fact srcstorepass can be ignored + testOK("changeit\n\n", "-importkeystore " + + "-srckeystore x.jceks -srcstoretype JCEKS " + + "-destkeystore x.jks -deststoretype JKS " + + "-srcalias c1 -destalias c2"); assertTrue(err.indexOf("WARNING") != -1, "But will warn"); - testOK("changeit\n\ny\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias c1 -destalias c2"); // 2nd import, press y to overwrite ... - testOK("changeit\n\n\nc3\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias c1 -destalias c2"); // ... or rename + // 2nd import, press y to overwrite ... + testOK("changeit\n\ny\n", "-importkeystore " + + "-srckeystore x.jceks -srcstoretype JCEKS " + + "-destkeystore x.jks -deststoretype JKS " + + "-srcalias c1 -destalias c2"); + // ... or rename + testOK("changeit\n\n\nc3\n", "-importkeystore " + + "-srckeystore x.jceks -srcstoretype JCEKS " + + "-destkeystore x.jks -deststoretype JKS " + + "-srcalias c1 -destalias c2"); ks = loadStore("x.jks", "changeit", "JKS"); - assertTrue(ks.size() == 3, "3 entries in JKS"); // c1, c2, c3 + // c1, c2, c3 + assertTrue(ks.size() == 3, "3 entries in JKS"); // importkeystore, secretkey remove("x.jks"); - testOK("changeit\n\n", "-keystore x.jceks -storetype JCEKS -genseckey -alias s1"); // create SecretKeyEntry - testOK("changeit\n\n", "-keystore x.jceks -storetype JCEKS -genseckey -alias s2"); // create SecretKeyEntry - testOK("changeit\n", "-keystore x.jceks -storetype JCEKS -delete -alias p2"); // remove the keypass!=storepass one + // create SecretKeyEntry + testOK("changeit\n\n", "-keystore x.jceks -storetype JCEKS " + + "-genseckey -alias s1"); + // create SecretKeyEntry + testOK("changeit\n\n", "-keystore x.jceks -storetype JCEKS " + + "-genseckey -alias s2"); + // remove the keypass!=storepass one + testOK("changeit\n", "-keystore x.jceks -storetype JCEKS " + + "-delete -alias p2"); ks = loadStore("x.jceks", "changeit", "JCEKS"); - assertTrue(ks.size() == 4, "4 entries in JCEKS"); // p1, c1, s1, s2 - testOK("changeit\nchangeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias s1"); // normal + // p1, c1, s1, s2 + assertTrue(ks.size() == 4, "4 entries in JCEKS"); + // normal + testOK("changeit\nchangeit\nchangeit\n", "-importkeystore " + + "-srckeystore x.jceks -srcstoretype JCEKS " + + "-destkeystore x.jks -deststoretype JKS -srcalias s1"); assertTrue(err.indexOf("not imported") != -1, "Not imported"); - assertTrue(err.indexOf("Cannot store non-PrivateKeys") != -1, "Not imported"); + assertTrue(err.indexOf("Cannot store non-PrivateKeys") != -1, + "Not imported"); - // Importing a JCEKS keystore to a JKS one. Will warn for the 2 SecretKey entries + // Importing a JCEKS keystore to a JKS one. Will warn + // for the 2 SecretKey entries remove("x.jks"); // Two "no" answers to bypass warnings - testOK("\n\n", "-srcstorepass changeit -deststorepass changeit -importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS"); // normal + // normal + testOK("\n\n", "-srcstorepass changeit -deststorepass changeit " + + "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS " + + "-destkeystore x.jks -deststoretype JKS"); assertTrue(err.indexOf("s1 not") != -1, "s1 not"); assertTrue(err.indexOf("s2 not") != -1, "s2 not"); assertTrue(err.indexOf("c1 success") != -1, "c1 success"); assertTrue(err.indexOf("p1 success") != -1, "p1 success"); remove("x.jks"); // One "yes" to stop - testOK("yes\n", "-srcstorepass changeit -deststorepass changeit -importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS"); // normal - // maybe c1 or p1 has been imported before s1 or s2 is touched, anyway we know yesNo is only asked once. + // normal + testOK("yes\n", "-srcstorepass changeit -deststorepass changeit " + + "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS " + + "-destkeystore x.jks -deststoretype JKS"); + // maybe c1 or p1 has been imported before s1 or s2 is touched, + // anyway we know yesNo is only asked once. // pkcs12 remove("x.jks"); - testFail("changeit\nchangeit\n", "-keystore x.jks -storetype JKS -genkeypair -alias p1 -dname CN=olala"); // JKS prompt for keypass + // JKS prompt for keypass + testFail("changeit\nchangeit\n", "-keystore x.jks -storetype JKS " + + "-genkeypair -alias p1 -dname CN=olala"); remove("x.jks"); - testOK("changeit\nchangeit\n\n", "-keystore x.jks -storetype JKS -genkeypair -alias p1 -dname CN=olala"); // just type ENTER means keypass=storepass + // just type ENTER means keypass=storepass + testOK("changeit\nchangeit\n\n", "-keystore x.jks -storetype JKS " + + "-genkeypair -alias p1 -dname CN=olala"); remove("x.p12"); - testOK("", "-keystore x.p12 -storetype PKCS12 -storepass changeit -genkeypair -alias p0 -dname CN=olala"); // PKCS12 only need storepass - testOK("changeit\n", "-keystore x.p12 -storetype PKCS12 -genkeypair -alias p1 -dname CN=olala"); - testOK("changeit\n", "-keystore x.p12 -keypass changeit -storetype PKCS12 -genkeypair -alias p3 -dname CN=olala"); // when specify keypass, make sure keypass==storepass... - assertTrue(err.indexOf("Warning") == -1, "PKCS12 silent when keypass == storepass"); - testOK("changeit\n", "-keystore x.p12 -keypass another -storetype PKCS12 -genkeypair -alias p2 -dname CN=olala"); // otherwise, print a warning - assertTrue(err.indexOf("Warning") != -1, "PKCS12 warning when keypass != storepass"); - testFail("", "-keystore x.p12 -storepass changeit -storetype PKCS12 -keypasswd -new changeit -alias p3"); // no -keypasswd for PKCS12 - testOK("", "-keystore x.p12 -storepass changeit -storetype PKCS12 -changealias -alias p3 -destalias p33"); - testOK("", "-keystore x.p12 -storepass changeit -storetype PKCS12 -keyclone -alias p33 -destalias p3"); + // PKCS12 only need storepass + testOK("", "-keystore x.p12 -storetype PKCS12 -storepass changeit " + + "-genkeypair -alias p0 -dname CN=olala"); + testOK("changeit\n", "-keystore x.p12 -storetype PKCS12 " + + "-genkeypair -alias p1 -dname CN=olala"); + // when specify keypass, make sure keypass==storepass... + testOK("changeit\n", "-keystore x.p12 -keypass changeit " + + "-storetype PKCS12 -genkeypair -alias p3 -dname CN=olala"); + assertTrue(err.indexOf("Warning") == -1, + "PKCS12 silent when keypass == storepass"); + // otherwise, print a warning + testOK("changeit\n", "-keystore x.p12 -keypass another" + + " -storetype PKCS12 -genkeypair -alias p2 -dname CN=olala"); + assertTrue(err.indexOf("Warning") != -1, + "PKCS12 warning when keypass != storepass"); + // no -keypasswd for PKCS12 + testFail("", "-keystore x.p12 -storepass changeit -storetype PKCS12" + + " -keypasswd -new changeit -alias p3"); + testOK("", "-keystore x.p12 -storepass changeit -storetype PKCS12 " + + "-changealias -alias p3 -destalias p33"); + testOK("", "-keystore x.p12 -storepass changeit -storetype PKCS12 " + + "-keyclone -alias p33 -destalias p3"); // pkcs12 remove("x.p12"); - testOK("", "-keystore x.p12 -storetype PKCS12 -storepass changeit -genkeypair -alias p0 -dname CN=olala"); // PKCS12 only need storepass - testOK("", "-storepass changeit -keystore x.p12 -storetype PKCS12 -genkeypair -alias p1 -dname CN=olala"); - testOK("", "-storepass changeit -keystore x.p12 -keypass changeit -storetype PKCS12 -genkeypair -alias p3 -dname CN=olala"); // when specify keypass, make sure keypass==storepass... - assertTrue(err.indexOf("Warning") == -1, "PKCS12 silent when keypass == storepass"); - testOK("", "-storepass changeit -keystore x.p12 -keypass another -storetype PKCS12 -genkeypair -alias p2 -dname CN=olala"); // otherwise, print a warning - assertTrue(err.indexOf("Warning") != -1, "PKCS12 warning when keypass != storepass"); + // PKCS12 only need storepass + testOK("", "-keystore x.p12 -storetype PKCS12 -storepass changeit " + + "-genkeypair -alias p0 -dname CN=olala"); + testOK("", "-storepass changeit -keystore x.p12 -storetype PKCS12 " + + "-genkeypair -alias p1 -dname CN=olala"); + // when specify keypass, make sure keypass==storepass... + testOK("", "-storepass changeit -keystore x.p12 -keypass changeit " + + "-storetype PKCS12 -genkeypair -alias p3 -dname CN=olala"); + assertTrue(err.indexOf("Warning") == -1, + "PKCS12 silent when keypass == storepass"); + // otherwise, print a warning + testOK("", "-storepass changeit -keystore x.p12 -keypass another " + + "-storetype PKCS12 -genkeypair -alias p2 -dname CN=olala"); + assertTrue(err.indexOf("Warning") != -1, + "PKCS12 warning when keypass != storepass"); remove("x.jks"); remove("x.jceks"); @@ -512,7 +671,7 @@ public class KeyToolTest { void testPKCS11() throws Exception { KeyStore ks; - // pkcs11, the password maybe different and maybe PKCS11 is not supported + // pkcs11, the password maybe different and maybe PKCS11 not supported // in case last test is not executed successfully testAnyway("", p11Arg + "-storepass test12 -delete -alias p1"); @@ -521,75 +680,97 @@ public class KeyToolTest { testAnyway("", p11Arg + "-storepass test12 -delete -alias nss"); testOK("", p11Arg + "-storepass test12 -list"); - assertTrue(out.indexOf("Your keystore contains 0 entries") != -1, "*** MAKE SURE YOU HAVE NO ENTRIES IN YOUR PKCS11 KEYSTORE BEFORE THIS TEST ***"); + assertTrue(out.indexOf("Your keystore contains 0 entries") != -1, + "*** MAKE SURE YOU HAVE NO ENTRIES IN YOUR PKCS11 KEYSTORE " + + "BEFORE THIS TEST ***"); - testOK("", p11Arg + "-storepass test12 -genkeypair -alias p1 -dname CN=olala"); + testOK("", p11Arg + + "-storepass test12 -genkeypair -alias p1 -dname CN=olala"); testOK("test12\n", p11Arg + "-genkeypair -alias p2 -dname CN=olala2"); - testFail("test12\n", p11Arg + "-keypass test12 -genkeypair -alias p3 -dname CN=olala3"); // cannot provide keypass for PKCS11 - testFail("test12\n", p11Arg + "-keypass nonsense -genkeypair -alias p3 -dname CN=olala3"); // cannot provide keypass for PKCS11 + // cannot provide keypass for PKCS11 + testFail("test12\n", p11Arg + + "-keypass test12 -genkeypair -alias p3 -dname CN=olala3"); + // cannot provide keypass for PKCS11 + testFail("test12\n", p11Arg + + "-keypass nonsense -genkeypair -alias p3 -dname CN=olala3"); testOK("", p11Arg + "-storepass test12 -list"); - assertTrue(out.indexOf("Your keystore contains 2 entries") != -1, "2 entries in p11"); + assertTrue(out.indexOf("Your keystore contains 2 entries") != -1, + "2 entries in p11"); testOK("test12\n", p11Arg + "-alias p1 -changealias -destalias p3"); testOK("", p11Arg + "-storepass test12 -list -alias p3"); testFail("", p11Arg + "-storepass test12 -list -alias p1"); testOK("test12\n", p11Arg + "-alias p3 -keyclone -destalias p1"); - testFail("", p11Arg + "-storepass test12 -list -alias p3"); // in PKCS11, keyclone will delete old + // in PKCS11, keyclone will delete old + testFail("", p11Arg + "-storepass test12 -list -alias p3"); testOK("", p11Arg + "-storepass test12 -list -alias p1"); - testFail("test12\n", p11Arg + "-alias p1 -keypasswd -new another"); // cannot change password for PKCS11 + // cannot change password for PKCS11 + testFail("test12\n", p11Arg + "-alias p1 -keypasswd -new another"); testOK("", p11Arg + "-storepass test12 -list"); - assertTrue(out.indexOf("Your keystore contains 2 entries") != -1, "2 entries in p11"); + assertTrue(out.indexOf("Your keystore contains 2 entries") != -1, + "2 entries in p11"); testOK("", p11Arg + "-storepass test12 -delete -alias p1"); testOK("", p11Arg + "-storepass test12 -delete -alias p2"); testOK("", p11Arg + "-storepass test12 -list"); - assertTrue(out.indexOf("Your keystore contains 0 entries") != -1, "*** MAKE SURE YOU HAVE NO ENTRIES IN YOUR PKCS11 KEYSTORE BEFORE THIS TEST ***"); + assertTrue(out.indexOf("Your keystore contains 0 entries") != -1, + "*** MAKE SURE YOU HAVE NO ENTRIES IN YOUR PKCS11 KEYSTORE" + + " BEFORE THIS TEST ***"); } void testPKCS11ImportKeyStore() throws Exception { KeyStore ks; - testOK("", p11Arg + "-storepass test12 -genkeypair -alias p1 -dname CN=olala"); + testOK("", p11Arg + + "-storepass test12 -genkeypair -alias p1 -dname CN=olala"); testOK("test12\n", p11Arg + "-genkeypair -alias p2 -dname CN=olala2"); // test importkeystore for pkcs11 remove("x.jks"); // pkcs11 -> jks - testOK("changeit\nchangeit\ntest12\n", srcP11Arg + "-importkeystore -destkeystore x.jks -deststoretype JKS -srcalias p1"); - assertTrue(err.indexOf("not imported") != -1, "cannot import key without destkeypass"); + testOK("changeit\nchangeit\ntest12\n", srcP11Arg + + ("-importkeystore -destkeystore x.jks -deststoretype JKS " + + "-srcalias p1")); + assertTrue(err.indexOf("not imported") != -1, + "cannot import key without destkeypass"); ks = loadStore("x.jks", "changeit", "JKS"); assertTrue(!ks.containsAlias("p1"), "p1 is not imported"); - testOK("changeit\ntest12\n", srcP11Arg + "-importkeystore -destkeystore x.jks -deststoretype JKS -srcalias p1 -destkeypass changeit"); - testOK("changeit\ntest12\n", srcP11Arg + "-importkeystore -destkeystore x.jks -deststoretype JKS -srcalias p2 -destkeypass changeit"); + testOK("changeit\ntest12\n", srcP11Arg + + ("-importkeystore -destkeystore x.jks -deststoretype JKS " + + "-srcalias p1 -destkeypass changeit")); + testOK("changeit\ntest12\n", srcP11Arg + + ("-importkeystore -destkeystore x.jks -deststoretype JKS " + + "-srcalias p2 -destkeypass changeit")); ks = loadStore("x.jks", "changeit", "JKS"); assertTrue(ks.containsAlias("p1"), "p1 is imported"); assertTrue(ks.containsAlias("p2"), "p2 is imported"); // jks -> pkcs11 testOK("", p11Arg + "-storepass test12 -delete -alias p1"); testOK("", p11Arg + "-storepass test12 -delete -alias p2"); - testOK("test12\nchangeit\n", p11Arg + "-importkeystore -srckeystore x.jks -srcstoretype JKS"); + testOK("test12\nchangeit\n", p11Arg + + "-importkeystore -srckeystore x.jks -srcstoretype JKS"); testOK("", p11Arg + "-storepass test12 -list -alias p1"); testOK("", p11Arg + "-storepass test12 -list -alias p2"); testOK("", p11Arg + "-storepass test12 -list"); - assertTrue(out.indexOf("Your keystore contains 2 entries") != -1, "2 entries in p11"); + assertTrue(out.indexOf("Your keystore contains 2 entries") != -1, + "2 entries in p11"); // clean up testOK("", p11Arg + "-storepass test12 -delete -alias p1"); testOK("", p11Arg + "-storepass test12 -delete -alias p2"); testOK("", p11Arg + "-storepass test12 -list"); - assertTrue(out.indexOf("Your keystore contains 0 entries") != -1, "empty p11"); + assertTrue(out.indexOf("Your keystore contains 0 entries") != -1, + "empty p11"); remove("x.jks"); } - // The sqeTest reflects the test suggested by judy.gao and bill.situ at - // /net/sqesvr-nfs/global/nfs/sec/ws_6.0_int/security/src/SecurityTools/Keytool - // + // Selected sqeTest void sqeTest() throws Exception { FileOutputStream fos = new FileOutputStream("badkeystore"); for (int i=0; i<100; i++) { @@ -616,79 +797,131 @@ public class KeyToolTest { void sqeImportTest() throws Exception { KeyStore ks; remove("x.jks"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -exportcert -file x.jks.p1.cert"); - /* deleted */ testOK("", "-keystore x.jks -storetype JKS -storepass changeit -delete -alias mykey"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -importcert -file x.jks.p1.cert -noprompt"); - /* deleted */ testOK("", "-keystore x.jks -storetype JKS -storepass changeit -delete -alias mykey"); - testOK("yes\n", "-keystore x.jks -storetype JKS -storepass changeit -importcert -file x.jks.p1.cert"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-exportcert -file x.jks.p1.cert"); + /* deleted */ testOK("", "-keystore x.jks -storetype JKS " + + "-storepass changeit -delete -alias mykey"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-importcert -file x.jks.p1.cert -noprompt"); + /* deleted */ testOK("", "-keystore x.jks -storetype JKS " + + "-storepass changeit -delete -alias mykey"); + testOK("yes\n", "-keystore x.jks -storetype JKS -storepass changeit " + + "-importcert -file x.jks.p1.cert"); ks = loadStore("x.jks", "changeit", "JKS"); assertTrue(ks.containsAlias("mykey"), "imported"); - /* deleted */ testOK("", "-keystore x.jks -storetype JKS -storepass changeit -delete -alias mykey"); - testOK("\n", "-keystore x.jks -storetype JKS -storepass changeit -importcert -file x.jks.p1.cert"); + /* deleted */ testOK("", "-keystore x.jks -storetype JKS " + + "-storepass changeit -delete -alias mykey"); + testOK("\n", "-keystore x.jks -storetype JKS -storepass changeit " + + "-importcert -file x.jks.p1.cert"); ks = loadStore("x.jks", "changeit", "JKS"); assertTrue(!ks.containsAlias("mykey"), "imported"); - testOK("no\n", "-keystore x.jks -storetype JKS -storepass changeit -importcert -file x.jks.p1.cert"); + testOK("no\n", "-keystore x.jks -storetype JKS -storepass changeit " + + "-importcert -file x.jks.p1.cert"); ks = loadStore("x.jks", "changeit", "JKS"); assertTrue(!ks.containsAlias("mykey"), "imported"); - testFail("no\n", "-keystore x.jks -storetype JKS -storepass changeit -importcert -file nonexist"); - testFail("no\n", "-keystore x.jks -storetype JKS -storepass changeit -importcert -file x.jks"); + testFail("no\n", "-keystore x.jks -storetype JKS -storepass changeit " + + "-importcert -file nonexist"); + testFail("no\n", "-keystore x.jks -storetype JKS -storepass changeit " + + "-importcert -file x.jks"); remove("x.jks"); } // keyclone: exist. nonexist err, cert err, dest exist, misc void sqeKeyclonetest() throws Exception { remove("x.jks"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -new newpass -keyclone -dest p0"); // new pass - testOK("\n", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -keyclone -dest p1"); // new pass - testOK("\n", "-keystore x.jks -storetype JKS -storepass changeit -keyclone -dest p2"); - testFail("\n", "-keystore x.jks -storetype JKS -storepass changeit -keyclone -dest p2"); - testFail("\n", "-keystore x.jks -storetype JKS -storepass changeit -keyclone -dest p3 -alias noexist"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala"); + // new pass + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -new newpass -keyclone -dest p0"); + // new pass + testOK("\n", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -keyclone -dest p1"); + testOK("\n", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keyclone -dest p2"); + testFail("\n", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keyclone -dest p2"); + testFail("\n", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keyclone -dest p3 -alias noexist"); // no cert - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -exportcert -file x.jks.p1.cert"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -delete -alias mykey"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -importcert -file x.jks.p1.cert -noprompt"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -new newpass -keyclone -dest p0"); // new pass + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-exportcert -file x.jks.p1.cert"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-delete -alias mykey"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-importcert -file x.jks.p1.cert -noprompt"); + // new pass + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -new newpass -keyclone -dest p0"); remove("x.jks"); } // keypasswd: exist, short, nonexist err, cert err, misc void sqeKeypasswdTest() throws Exception { remove("x.jks"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -keypasswd -new newpass"); - /*change back*/ testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass newpass -keypasswd -new changeit"); - testOK("newpass\nnewpass\n", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -keypasswd"); - /*change back*/ testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass newpass -keypasswd -new changeit"); - testOK("new\nnew\nnewpass\nnewpass\n", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -keypasswd"); - /*change back*/ testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass newpass -keypasswd -new changeit"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypasswd -new newpass"); - /*change back*/ testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass newpass -keypasswd -new changeit"); - testOK("changeit\n", "-keystore x.jks -storetype JKS -keypasswd -new newpass"); - /*change back*/ testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass newpass -keypasswd -new changeit"); - testFail("", "-keystore x.jks -storetype JKS -storepass badpass -keypass changeit -keypasswd -new newpass"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -keypass bad -keypasswd -new newpass"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -keypasswd -new newpass"); + /*change back*/ testOK("", "-keystore x.jks -storetype JKS " + + "-storepass changeit -keypass newpass -keypasswd -new changeit"); + testOK("newpass\nnewpass\n", "-keystore x.jks -storetype JKS " + + "-storepass changeit -keypass changeit -keypasswd"); + /*change back*/ testOK("", "-keystore x.jks -storetype JKS " + + "-storepass changeit -keypass newpass -keypasswd -new changeit"); + testOK("new\nnew\nnewpass\nnewpass\n", "-keystore x.jks " + + "-storetype JKS -storepass changeit -keypass changeit -keypasswd"); + /*change back*/ testOK("", "-keystore x.jks -storetype JKS " + + "-storepass changeit -keypass newpass -keypasswd -new changeit"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypasswd -new newpass"); + /*change back*/ testOK("", "-keystore x.jks -storetype JKS " + + "-storepass changeit -keypass newpass -keypasswd -new changeit"); + testOK("changeit\n", "-keystore x.jks -storetype JKS " + + "-keypasswd -new newpass"); + /*change back*/ testOK("", "-keystore x.jks -storetype JKS " + + "-storepass changeit -keypass newpass -keypasswd -new changeit"); + testFail("", "-keystore x.jks -storetype JKS -storepass badpass " + + "-keypass changeit -keypasswd -new newpass"); + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass bad -keypasswd -new newpass"); // no cert - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -exportcert -file x.jks.p1.cert"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -delete -alias mykey"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -importcert -file x.jks.p1.cert -noprompt"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -keypasswd -new newpass"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-exportcert -file x.jks.p1.cert"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-delete -alias mykey"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-importcert -file x.jks.p1.cert -noprompt"); + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -keypasswd -new newpass"); // diff pass - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -delete -alias mykey"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass keypass -genkeypair -dname CN=olala"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -keypasswd -new newpass"); - testOK("keypass\n", "-keystore x.jks -storetype JKS -storepass changeit -keypasswd -new newpass"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-delete -alias mykey"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass keypass -genkeypair -dname CN=olala"); + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypasswd -new newpass"); + testOK("keypass\n", "-keystore x.jks -storetype JKS " + + "-storepass changeit -keypasswd -new newpass"); // i hate those misc test remove("x.jks"); } - // list: -f -alias, exist, nonexist err; otherwise, check all shows, -rfc shows more, and misc + // list: -f -alias, exist, nonexist err; + // otherwise, check all shows, -rfc shows more, and misc void sqeListTest() throws Exception { remove("x.jks"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala"); testOK("", "-keystore x.jks -storetype JKS -storepass changeit -list"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -list -alias mykey"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -list -alias notexist"); - testFail("", "-keystore x.jks -storetype JKS -storepass badpass -list -alias mykey"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass badpass -list -alias mykey"); // keypass ignore + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-list -alias mykey"); + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-list -alias notexist"); + testFail("", "-keystore x.jks -storetype JKS -storepass badpass " + + "-list -alias mykey"); + // keypass ignore + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass badpass -list -alias mykey"); testOK("\n", "-keystore x.jks -storetype JKS -list"); assertTrue(err.indexOf("WARNING") != -1, "no storepass"); testOK("changeit\n", "-keystore x.jks -storetype JKS -list"); @@ -700,92 +933,182 @@ public class KeyToolTest { testFail("", "-keystore badkeystore -storepass changeit -list"); remove("x.jks"); } - // selfcert: exist, non-exist err, cert err, sig..., dname, wrong keypass, misc + // selfcert: exist, non-exist err, cert err, sig, dname, wrong keypass, misc void sqeSelfCertTest() throws Exception { remove("x.jks"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala"); testOK("", "-keystore x.jks -storetype JKS -storepass changeit -selfcert"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -selfcert"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -selfcert -alias nonexisting"); // not exist - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -selfcert -dname CN=NewName"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -selfcert -sigalg MD5withRSA"); // sig not compatible - testFail("", "-keystore x.jks -storetype JKS -storepass wrong -keypass changeit -selfcert"); // bad pass - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -keypass wrong -selfcert"); // bad pass + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -selfcert"); + // not exist + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -selfcert -alias nonexisting"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -selfcert -dname CN=NewName"); + // sig not compatible + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -selfcert -sigalg MD5withRSA"); + // bad pass + testFail("", "-keystore x.jks -storetype JKS -storepass wrong " + + "-keypass changeit -selfcert"); + // bad pass + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass wrong -selfcert"); //misc - testFail("", "-keystore nonexist -storepass changeit -keypass changeit -selfcert"); - testFail("", "-keystore aa//dd\\gg -storepass changeit -keypass changeit -selfcert"); + testFail("", "-keystore nonexist -storepass changeit " + + "-keypass changeit -selfcert"); + testFail("", "-keystore aa//dd\\gg -storepass changeit " + + "-keypass changeit -selfcert"); // diff pass remove("x.jks"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass keypass -genkeypair -dname CN=olala"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -selfcert"); - testOK("keypass\n", "-keystore x.jks -storetype JKS -storepass changeit -selfcert"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass keypass -genkeypair -dname CN=olala"); + testFail("", "-keystore x.jks -storetype JKS " + + "-storepass changeit -selfcert"); + testOK("keypass\n", "-keystore x.jks -storetype JKS " + + "-storepass changeit -selfcert"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -exportcert -file x.jks.p1.cert"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -delete -alias mykey"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -importcert -file x.jks.p1.cert -noprompt"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -selfcert"); // certentry cannot do selfcert + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-exportcert -file x.jks.p1.cert"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-delete -alias mykey"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-importcert -file x.jks.p1.cert -noprompt"); + // certentry cannot do selfcert + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-selfcert"); remove("x.jks"); } // storepass: bad old, short new, misc void sqeStorepassTest() throws Exception { remove("x.jks"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala"); - testOK("", "-storepasswd -keystore x.jks -storetype JKS -storepass changeit -new newstore"); // all in arg - /* Change back */ testOK("", "-storepasswd -keystore x.jks -storetype JKS -storepass newstore -new changeit"); - testOK("changeit\nnewstore\nnewstore\n", "-storepasswd -keystore x.jks -storetype JKS"); // all not in arg, new twice - /* Change back */ testOK("", "-storepasswd -keystore x.jks -storetype JKS -storepass newstore -new changeit"); - testOK("changeit\n", "-storepasswd -keystore x.jks -storetype JKS -new newstore"); // new in arg - /* Change back */ testOK("", "-storepasswd -keystore x.jks -storetype JKS -storepass newstore -new changeit"); - testOK("newstore\nnewstore\n", "-storepasswd -keystore x.jks -storetype JKS -storepass changeit"); // old in arg - /* Change back */ testOK("", "-storepasswd -keystore x.jks -storetype JKS -storepass newstore -new changeit"); - testOK("new\nnew\nnewstore\nnewstore\n", "-storepasswd -keystore x.jks -storetype JKS -storepass changeit"); // old in arg - /* Change back */ testOK("", "-storepasswd -keystore x.jks -storetype JKS -storepass newstore -new changeit"); - testFail("", "-storepasswd -keystore x.jks -storetype JKS -storepass badold -new newstore"); // bad old - testFail("", "-storepasswd -keystore x.jks -storetype JKS -storepass changeit -new new"); // short new + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala"); + // all in arg + testOK("", "-storepasswd -keystore x.jks -storetype JKS " + + "-storepass changeit -new newstore"); + /* Change back */ testOK("", "-storepasswd -keystore x.jks" + + " -storetype JKS -storepass newstore -new changeit"); + // all not in arg, new twice + testOK("changeit\nnewstore\nnewstore\n", "-storepasswd " + + "-keystore x.jks -storetype JKS"); + /* Change back */ testOK("", "-storepasswd -keystore x.jks " + + "-storetype JKS -storepass newstore -new changeit"); + // new in arg + testOK("changeit\n", "-storepasswd -keystore x.jks " + + "-storetype JKS -new newstore"); + /* Change back */ testOK("", "-storepasswd -keystore x.jks " + + "-storetype JKS -storepass newstore -new changeit"); + // old in arg + testOK("newstore\nnewstore\n", "-storepasswd -keystore x.jks " + + "-storetype JKS -storepass changeit"); + /* Change back */ testOK("", "-storepasswd -keystore x.jks " + + "-storetype JKS -storepass newstore -new changeit"); + // old in arg + testOK("new\nnew\nnewstore\nnewstore\n", "-storepasswd " + + "-keystore x.jks -storetype JKS -storepass changeit"); + /* Change back */ testOK("", "-storepasswd -keystore x.jks " + + "-storetype JKS -storepass newstore -new changeit"); + // bad old + testFail("", "-storepasswd -keystore x.jks -storetype JKS " + + "-storepass badold -new newstore"); + // short new + testFail("", "-storepasswd -keystore x.jks -storetype JKS " + + "-storepass changeit -new new"); // misc - testFail("", "-storepasswd -keystore nonexist -storepass changeit -new newstore"); // non exist - testFail("", "-storepasswd -keystore badkeystore -storepass changeit -new newstore"); // bad file - testFail("", "-storepasswd -keystore aa\\bb//cc//dd -storepass changeit -new newstore"); // bad file + // non exist + testFail("", "-storepasswd -keystore nonexist " + + "-storepass changeit -new newstore"); + // bad file + testFail("", "-storepasswd -keystore badkeystore " + + "-storepass changeit -new newstore"); + // bad file + testFail("", "-storepasswd -keystore aa\\bb//cc//dd " + + "-storepass changeit -new newstore"); remove("x.jks"); } void sqeGenkeyTest() throws Exception { remove("x.jks"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala -alias newentry"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala -alias newentry"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg DSA -alias n1"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg RSA -alias n2"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg NoSuchAlg -alias n3"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keysize 56 -alias n4"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keysize 999 -alias n5"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keysize 512 -alias n6"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keysize 1024 -alias n7"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala -sigalg NoSuchAlg -alias n8"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg RSA -sigalg MD2withRSA -alias n9"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg RSA -sigalg MD5withRSA -alias n10"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg RSA -sigalg SHA1withRSA -alias n11"); - testFail("", "-keystore aa\\bb//cc\\dd -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg RSA -sigalg NoSuchAlg -alias n12"); - testFail("", "-keystore badkeystore -storepass changeit -keypass changeit -genkeypair -dname CN=olala -alias n14"); - testFail("", "-keystore x.jks -storetype JKS -storepass badpass -keypass changeit -genkeypair -dname CN=olala -alias n16"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CNN=olala -alias n17"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala"); + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala -alias newentry"); + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala -alias newentry"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala -keyalg DSA " + + "-alias n1"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala -keyalg RSA " + + "-alias n2"); + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala " + + "-keyalg NoSuchAlg -alias n3"); + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala -keysize 56 " + + "-alias n4"); + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala -keysize 999 " + + "-alias n5"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala -keysize 512 " + + "-alias n6"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala -keysize 1024 " + + "-alias n7"); + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala " + + "-sigalg NoSuchAlg -alias n8"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala -keyalg RSA " + + "-sigalg MD2withRSA -alias n9"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala -keyalg RSA " + + "-sigalg MD5withRSA -alias n10"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala -keyalg RSA " + + "-sigalg SHA1withRSA -alias n11"); + testFail("", "-keystore aa\\bb//cc\\dd -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala -keyalg RSA " + + "-sigalg NoSuchAlg -alias n12"); + testFail("", "-keystore badkeystore -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala " + + "-alias n14"); + testFail("", "-keystore x.jks -storetype JKS -storepass badpass " + + "-keypass changeit -genkeypair -dname CN=olala -alias n16"); + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CNN=olala -alias n17"); remove("x.jks"); } void sqeExportTest() throws Exception { remove("x.jks"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -export -file mykey.cert -alias mykey"); // nonexist - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -export -file mykey.cert -alias mykey"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -delete -alias mykey"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -import -file mykey.cert -noprompt -alias c1"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -export -file mykey.cert2 -alias c1"); - testFail("", "-keystore aa\\bb//cc\\dd -storepass changeit -export -file mykey.cert2 -alias c1"); - testFail("", "-keystore nonexistkeystore -storepass changeit -export -file mykey.cert2 -alias c1"); - testFail("", "-keystore badkeystore -storepass changeit -export -file mykey.cert2 -alias c1"); - testFail("", "-keystore x.jks -storetype JKS -storepass badpass -export -file mykey.cert2 -alias c1"); + // nonexist + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-export -file mykey.cert -alias mykey"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-export -file mykey.cert -alias mykey"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-delete -alias mykey"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-import -file mykey.cert -noprompt -alias c1"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-export -file mykey.cert2 -alias c1"); + testFail("", "-keystore aa\\bb//cc\\dd -storepass changeit " + + "-export -file mykey.cert2 -alias c1"); + testFail("", "-keystore nonexistkeystore -storepass changeit " + + "-export -file mykey.cert2 -alias c1"); + testFail("", "-keystore badkeystore -storepass changeit " + + "-export -file mykey.cert2 -alias c1"); + testFail("", "-keystore x.jks -storetype JKS -storepass badpass " + + "-export -file mykey.cert2 -alias c1"); remove("mykey.cert"); remove("mykey.cert2"); remove("x.jks"); @@ -793,14 +1116,27 @@ public class KeyToolTest { void sqeDeleteTest() throws Exception { remove("x.jks"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -delete -alias mykey"); // nonexist - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -delete -alias mykey"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala"); - testFail("", "-keystore aa\\bb//cc\\dd -storepass changeit -delete -alias mykey"); // keystore name illegal - testFail("", "-keystore nonexistkeystore -storepass changeit -delete -alias mykey"); // keystore not exist - testFail("", "-keystore badkeystore -storepass changeit -delete -alias mykey"); // keystore invalid - testFail("", "-keystore x.jks -storetype JKS -storepass xxxxxxxx -delete -alias mykey"); // wrong pass + // nonexist + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-delete -alias mykey"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-delete -alias mykey"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala"); + // keystore name illegal + testFail("", "-keystore aa\\bb//cc\\dd -storepass changeit " + + "-delete -alias mykey"); + // keystore not exist + testFail("", "-keystore nonexistkeystore -storepass changeit " + + "-delete -alias mykey"); + // keystore invalid + testFail("", "-keystore badkeystore -storepass changeit " + + "-delete -alias mykey"); + // wrong pass + testFail("", "-keystore x.jks -storetype JKS -storepass xxxxxxxx " + + "-delete -alias mykey"); remove("x.jks"); } @@ -809,31 +1145,61 @@ public class KeyToolTest { remove("x.jks.p1.cert"); remove("csr1"); // PrivateKeyEntry can do certreq - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keysize 1024"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -certreq -file csr1 -alias mykey"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -certreq -file csr1"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -certreq -file csr1 -sigalg SHA1withDSA"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -certreq -file csr1 -sigalg MD5withRSA"); // unmatched sigalg + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala -keysize 1024"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-certreq -file csr1 -alias mykey"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-certreq -file csr1"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-certreq -file csr1 -sigalg SHA1withDSA"); + // unmatched sigalg + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-certreq -file csr1 -sigalg MD5withRSA"); // misc test - testFail("", "-keystore x.jks -storetype JKS -storepass badstorepass -certreq -file csr1"); // bad storepass - testOK("changeit\n", "-keystore x.jks -storetype JKS -certreq -file csr1"); // storepass from terminal - testFail("\n", "-keystore x.jks -storetype JKS -certreq -file csr1"); // must provide storepass - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -keypass badkeypass -certreq -file csr1"); // bad keypass - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -certreq -file aa\\bb//cc\\dd"); // bad filepath - testFail("", "-keystore noexistks -storepass changeit -certreq -file csr1"); // non-existing keystore + // bad storepass + testFail("", "-keystore x.jks -storetype JKS -storepass badstorepass " + + "-certreq -file csr1"); + // storepass from terminal + testOK("changeit\n", "-keystore x.jks -storetype JKS " + + "-certreq -file csr1"); + // must provide storepass + testFail("\n", "-keystore x.jks -storetype JKS " + + "-certreq -file csr1"); + // bad keypass + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass badkeypass -certreq -file csr1"); + // bad filepath + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-certreq -file aa\\bb//cc\\dd"); + // non-existing keystore + testFail("", "-keystore noexistks -storepass changeit " + + "-certreq -file csr1"); // Try the RSA private key - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -delete -alias mykey"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg RSA"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -certreq -file csr1 -alias mykey"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -certreq -file csr1"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -certreq -file csr1 -sigalg SHA1withDSA"); // unmatched sigalg - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -certreq -file csr1 -sigalg MD5withRSA"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-delete -alias mykey"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala -keyalg RSA"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-certreq -file csr1 -alias mykey"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-certreq -file csr1"); + // unmatched sigalg + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-certreq -file csr1 -sigalg SHA1withDSA"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-certreq -file csr1 -sigalg MD5withRSA"); // TrustedCertificateEntry cannot do certreq - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -exportcert -file x.jks.p1.cert"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -delete -alias mykey"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -importcert -file x.jks.p1.cert -noprompt"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -certreq -file csr1 -alias mykey"); - testFail("", "-keystore x.jks -storetype JKS -storepass changeit -certreq -file csr1"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-exportcert -file x.jks.p1.cert"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-delete -alias mykey"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-importcert -file x.jks.p1.cert -noprompt"); + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-certreq -file csr1 -alias mykey"); + testFail("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-certreq -file csr1"); remove("x.jks"); remove("x.jks.p1.cert"); remove("csr1"); @@ -842,8 +1208,10 @@ public class KeyToolTest { void sqePrintcertTest() throws Exception { remove("x.jks"); remove("mykey.cert"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -genkeypair -dname CN=olala"); - testOK("", "-keystore x.jks -storetype JKS -storepass changeit -export -file mykey.cert -alias mykey"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -genkeypair -dname CN=olala"); + testOK("", "-keystore x.jks -storetype JKS -storepass changeit " + + "-export -file mykey.cert -alias mykey"); testFail("", "-printcert -file badkeystore"); testFail("", "-printcert -file a/b/c/d"); testOK("", "-printcert -file mykey.cert"); @@ -857,7 +1225,8 @@ public class KeyToolTest { void v3extTest(String keyAlg) throws Exception { KeyStore ks; remove("x.jks"); - String simple = "-keystore x.jks -storetype JKS -storepass changeit -keypass changeit -noprompt -keyalg " + keyAlg + " "; + String simple = "-keystore x.jks -storetype JKS -storepass changeit " + + "-keypass changeit -noprompt -keyalg " + keyAlg + " "; String pre = simple + "-genkeypair -dname CN=Olala -alias "; // Version and SKID @@ -865,7 +1234,8 @@ public class KeyToolTest { ks = loadStore("x.jks", "changeit", "JKS"); assertTrue(((X509Certificate)ks.getCertificate("o1")).getVersion() == 3); - assertTrue(((X509CertImpl)ks.getCertificate("o1")).getSubjectKeyIdentifierExtension() != null); + assertTrue(((X509CertImpl)ks.getCertificate("o1")) + .getSubjectKeyIdentifierExtension() != null); // BC testOK("", pre + "b1 -ext BC:critical"); @@ -879,29 +1249,44 @@ public class KeyToolTest { testOK("", pre + "b9 -ext BC=12"); ks = loadStore("x.jks", "changeit", "JKS"); - assertTrue(((X509CertImpl)ks.getCertificate("b1")).getBasicConstraintsExtension().isCritical()); - assertTrue(!((X509CertImpl)ks.getCertificate("b2")).getBasicConstraintsExtension().isCritical()); - assertTrue(((X509CertImpl)ks.getCertificate("b8")).getBasicConstraintsExtension().isCritical()); - assertTrue(((X509Certificate)ks.getCertificate("b1")).getBasicConstraints() == Integer.MAX_VALUE); - assertTrue(((X509Certificate)ks.getCertificate("b2")).getBasicConstraints() == Integer.MAX_VALUE); - assertTrue(((X509Certificate)ks.getCertificate("b3")).getBasicConstraints() == Integer.MAX_VALUE); - assertTrue(((X509Certificate)ks.getCertificate("b4")).getBasicConstraints() == Integer.MAX_VALUE); - assertTrue(((X509Certificate)ks.getCertificate("b5")).getBasicConstraints() == Integer.MAX_VALUE); - assertTrue(((X509Certificate)ks.getCertificate("b6")).getBasicConstraints() == 12); - assertTrue(((X509Certificate)ks.getCertificate("b7")).getBasicConstraints() == -1); - assertTrue(((X509Certificate)ks.getCertificate("b9")).getBasicConstraints() == 12); + assertTrue(((X509CertImpl)ks.getCertificate("b1")) + .getBasicConstraintsExtension().isCritical()); + assertTrue(!((X509CertImpl)ks.getCertificate("b2")) + .getBasicConstraintsExtension().isCritical()); + assertTrue(((X509CertImpl)ks.getCertificate("b8")) + .getBasicConstraintsExtension().isCritical()); + assertTrue(((X509Certificate)ks.getCertificate("b1")) + .getBasicConstraints() == Integer.MAX_VALUE); + assertTrue(((X509Certificate)ks.getCertificate("b2")) + .getBasicConstraints() == Integer.MAX_VALUE); + assertTrue(((X509Certificate)ks.getCertificate("b3")) + .getBasicConstraints() == Integer.MAX_VALUE); + assertTrue(((X509Certificate)ks.getCertificate("b4")) + .getBasicConstraints() == Integer.MAX_VALUE); + assertTrue(((X509Certificate)ks.getCertificate("b5")) + .getBasicConstraints() == Integer.MAX_VALUE); + assertTrue(((X509Certificate)ks.getCertificate("b6")) + .getBasicConstraints() == 12); + assertTrue(((X509Certificate)ks.getCertificate("b7")) + .getBasicConstraints() == -1); + assertTrue(((X509Certificate)ks.getCertificate("b9")) + .getBasicConstraints() == 12); // KU testOK("", pre + "ku1 -ext KeyUsage:critical=digitalsignature"); testOK("", pre + "ku2 -ext KU=digitalSignature"); testOK("", pre + "ku3 -ext KU=ds"); testOK("", pre + "ku4 -ext KU=dig"); - testFail("", pre + "ku5 -ext KU=d"); // ambigous value - testFail("", pre + "ku6 -ext KU=cs"); // cRLSign cannot be cs + // ambigous value + testFail("", pre + "ku5 -ext KU=d"); + // cRLSign cannot be cs + testFail("", pre + "ku6 -ext KU=cs"); testOK("", pre + "ku11 -ext KU=nr"); - testFail("", pre + "ku12 -ext KU=ke"); // ke also means keyAgreement + // ke also means keyAgreement + testFail("", pre + "ku12 -ext KU=ke"); testOK("", pre + "ku12 -ext KU=keyE"); - testFail("", pre + "ku13 -ext KU=de"); // de also means decipherOnly + // de also means decipherOnly + testFail("", pre + "ku13 -ext KU=de"); testOK("", pre + "ku13 -ext KU=dataE"); testOK("", pre + "ku14 -ext KU=ka"); testOK("", pre + "ku15 -ext KU=kcs"); @@ -919,7 +1304,8 @@ public class KeyToolTest { class CheckKU { void check(KeyStore ks, String alias, int... pos) throws Exception { System.err.print("x"); - boolean[] bs = ((X509Certificate)ks.getCertificate(alias)).getKeyUsage(); + boolean[] bs = ((X509Certificate)ks.getCertificate(alias)) + .getKeyUsage(); bs = Arrays.copyOf(bs, 9); for (int i=0; i bs = ((X509Certificate)ks.getCertificate(alias)).getExtendedKeyUsage(); + List bs = ((X509Certificate)ks.getCertificate(alias)) + .getExtendedKeyUsage(); int found = 0; for (String p: pos) { if (bs.contains(p)) { @@ -991,8 +1380,10 @@ public class KeyToolTest { } } CheckEKU cx = new CheckEKU(); - assertTrue(((X509CertImpl)ks.getCertificate("eku1")).getExtension(PKIXExtensions.ExtendedKeyUsage_Id).isCritical()); - assertTrue(!((X509CertImpl)ks.getCertificate("eku2")).getExtension(PKIXExtensions.ExtendedKeyUsage_Id).isCritical()); + assertTrue(((X509CertImpl)ks.getCertificate("eku1")) + .getExtension(PKIXExtensions.ExtendedKeyUsage_Id).isCritical()); + assertTrue(!((X509CertImpl)ks.getCertificate("eku2")) + .getExtension(PKIXExtensions.ExtendedKeyUsage_Id).isCritical()); cx.check(ks, "eku1", "1.3.6.1.5.5.7.3.1"); cx.check(ks, "eku2", "1.3.6.1.5.5.7.3.2"); cx.check(ks, "eku3", "1.3.6.1.5.5.7.3.3"); @@ -1013,12 +1404,15 @@ public class KeyToolTest { ks = loadStore("x.jks", "changeit", "JKS"); class CheckSAN { // Please sort items with name type - void check(KeyStore ks, String alias, int type, Object... items) throws Exception { + void check(KeyStore ks, String alias, int type, Object... items) + throws Exception { int pos = 0; System.err.print("x"); Object[] names = null; - if (type == 0) names = ((X509Certificate)ks.getCertificate(alias)).getSubjectAlternativeNames().toArray(); - else names = ((X509Certificate)ks.getCertificate(alias)).getIssuerAlternativeNames().toArray(); + if (type == 0) names = ((X509Certificate)ks.getCertificate(alias)) + .getSubjectAlternativeNames().toArray(); + else names = ((X509Certificate)ks.getCertificate(alias)) + .getIssuerAlternativeNames().toArray(); Arrays.sort(names, new Comparator() { public int compare(Object o1, Object o2) { int i1 = (Integer)((List)o1).get(0); @@ -1041,8 +1435,10 @@ public class KeyToolTest { } } CheckSAN csan = new CheckSAN(); - assertTrue(((X509CertImpl)ks.getCertificate("san1")).getSubjectAlternativeNameExtension().isCritical()); - assertTrue(!((X509CertImpl)ks.getCertificate("san2")).getSubjectAlternativeNameExtension().isCritical()); + assertTrue(((X509CertImpl)ks.getCertificate("san1")) + .getSubjectAlternativeNameExtension().isCritical()); + assertTrue(!((X509CertImpl)ks.getCertificate("san2")) + .getSubjectAlternativeNameExtension().isCritical()); csan.check(ks, "san1", 0, 1, "me@me.org"); csan.check(ks, "san2", 0, 6, "http://me.org"); csan.check(ks, "san3", 0, 2, "me.org"); @@ -1059,8 +1455,10 @@ public class KeyToolTest { testOK("", pre+"ian235 -ext ian=uri:http://me.org,dns:me.org,oid:1.2.3.4"); ks = loadStore("x.jks", "changeit", "JKS"); - assertTrue(((X509CertImpl)ks.getCertificate("ian1")).getIssuerAlternativeNameExtension().isCritical()); - assertTrue(!((X509CertImpl)ks.getCertificate("ian2")).getIssuerAlternativeNameExtension().isCritical()); + assertTrue(((X509CertImpl)ks.getCertificate("ian1")) + .getIssuerAlternativeNameExtension().isCritical()); + assertTrue(!((X509CertImpl)ks.getCertificate("ian2")) + .getIssuerAlternativeNameExtension().isCritical()); csan.check(ks, "ian1", 1, 1, "me@me.org"); csan.check(ks, "ian2", 1, 6, "http://me.org"); csan.check(ks, "ian3", 1, 2, "me.org"); @@ -1071,63 +1469,85 @@ public class KeyToolTest { // SIA testOK("", pre+"sia1 -ext sia=care:uri:ldap://ca.com/cn=CA"); testOK("", pre+"sia2 -ext sia=ts:email:ts@ca.com"); - testFail("SIA never critical", pre+"sia3 -ext sia:critical=ts:email:ts@ca.com"); + testFail("SIA never critical", pre + + "sia3 -ext sia:critical=ts:email:ts@ca.com"); ks = loadStore("x.jks", "changeit", "JKS"); class CheckSia { - void check(KeyStore ks, String alias, int type, Object... items) throws Exception { + void check(KeyStore ks, String alias, int type, Object... items) + throws Exception { int pos = 0; System.err.print("x"); AccessDescription[] ads = null; if (type == 0) { - SubjectInfoAccessExtension siae = (SubjectInfoAccessExtension)((X509CertImpl)ks.getCertificate(alias)).getExtension(PKIXExtensions.SubjectInfoAccess_Id); - ads = siae.getAccessDescriptions().toArray(new AccessDescription[0]); + SubjectInfoAccessExtension siae = (SubjectInfoAccessExtension) + ((X509CertImpl)ks.getCertificate(alias)) + .getExtension(PKIXExtensions.SubjectInfoAccess_Id); + ads = siae.getAccessDescriptions() + .toArray(new AccessDescription[0]); } else { - AuthorityInfoAccessExtension aiae = (AuthorityInfoAccessExtension)((X509CertImpl)ks.getCertificate(alias)).getExtension(PKIXExtensions.AuthInfoAccess_Id); - ads = aiae.getAccessDescriptions().toArray(new AccessDescription[0]); + AuthorityInfoAccessExtension aiae = + (AuthorityInfoAccessExtension) + ((X509CertImpl)ks.getCertificate(alias)) + .getExtension(PKIXExtensions.AuthInfoAccess_Id); + ads = aiae.getAccessDescriptions() + .toArray(new AccessDescription[0]); } Arrays.sort(ads, new Comparator() { @Override - public int compare(AccessDescription o1, AccessDescription o2) { - return o1.getAccessMethod().toString().compareTo(o2.getAccessMethod().toString()); + public int compare(AccessDescription o1, + AccessDescription o2) { + return o1.getAccessMethod().toString() + .compareTo(o2.getAccessMethod().toString()); } }); for (AccessDescription ad: ads) { if (!ad.getAccessMethod().equals(items[pos++]) || - !new Integer(ad.getAccessLocation().getType()).equals(items[pos++])) { + !new Integer(ad.getAccessLocation().getType()) + .equals(items[pos++])) { throw new RuntimeException("Not same type at " + pos); } String name = null; switch (ad.getAccessLocation().getType()) { case 1: - name = ((RFC822Name)ad.getAccessLocation().getName()).getName(); + name = ((RFC822Name)ad.getAccessLocation() + .getName()).getName(); break; case 6: - name = ((URIName)ad.getAccessLocation().getName()).getURI().toString(); + name = ((URIName)ad.getAccessLocation() + .getName()).getURI().toString(); break; default: throw new RuntimeException("Not implemented: " + ad); } if (!name.equals(items[pos++])) { - throw new Exception("Name not same for " + ad + " at pos " + pos); + throw new Exception("Name not same for " + ad + + " at pos " + pos); } } } } CheckSia csia = new CheckSia(); - assertTrue(!((X509CertImpl)ks.getCertificate("sia1")).getExtension(PKIXExtensions.SubjectInfoAccess_Id).isCritical()); - csia.check(ks, "sia1", 0, AccessDescription.Ad_CAREPOSITORY_Id, 6, "ldap://ca.com/cn=CA"); - csia.check(ks, "sia2", 0, AccessDescription.Ad_TIMESTAMPING_Id, 1, "ts@ca.com"); + assertTrue(!((X509CertImpl)ks.getCertificate("sia1")) + .getExtension(PKIXExtensions.SubjectInfoAccess_Id).isCritical()); + csia.check(ks, "sia1", 0, + AccessDescription.Ad_CAREPOSITORY_Id, 6, "ldap://ca.com/cn=CA"); + csia.check(ks, "sia2", + 0, AccessDescription.Ad_TIMESTAMPING_Id, 1, "ts@ca.com"); // AIA testOK("", pre+"aia1 -ext aia=cai:uri:ldap://ca.com/cn=CA"); testOK("", pre+"aia2 -ext aia=ocsp:email:ocsp@ca.com"); - testFail("AIA never critical", pre+"aia3 -ext aia:critical=ts:email:ts@ca.com"); + testFail("AIA never critical", pre + + "aia3 -ext aia:critical=ts:email:ts@ca.com"); ks = loadStore("x.jks", "changeit", "JKS"); - assertTrue(!((X509CertImpl)ks.getCertificate("aia1")).getExtension(PKIXExtensions.AuthInfoAccess_Id).isCritical()); - csia.check(ks, "aia1", 1, AccessDescription.Ad_CAISSUERS_Id, 6, "ldap://ca.com/cn=CA"); - csia.check(ks, "aia2", 1, AccessDescription.Ad_OCSP_Id, 1, "ocsp@ca.com"); + assertTrue(!((X509CertImpl)ks.getCertificate("aia1")) + .getExtension(PKIXExtensions.AuthInfoAccess_Id).isCritical()); + csia.check(ks, "aia1", 1, + AccessDescription.Ad_CAISSUERS_Id, 6, "ldap://ca.com/cn=CA"); + csia.check(ks, "aia2", 1, + AccessDescription.Ad_OCSP_Id, 1, "ocsp@ca.com"); // OID testOK("", pre+"oid1 -ext 1.2.3:critical=0102"); @@ -1136,18 +1556,23 @@ public class KeyToolTest { ks = loadStore("x.jks", "changeit", "JKS"); class CheckOid { - void check(KeyStore ks, String alias, String oid, byte[] value) throws Exception { + void check(KeyStore ks, String alias, String oid, byte[] value) + throws Exception { int pos = 0; System.err.print("x"); - Extension ex = ((X509CertImpl)ks.getCertificate(alias)).getExtension(new ObjectIdentifier(oid)); + Extension ex = ((X509CertImpl)ks.getCertificate(alias)) + .getExtension(new ObjectIdentifier(oid)); if (!Arrays.equals(value, ex.getValue())) { - throw new RuntimeException("Not same content in " + alias + " for " + oid); + throw new RuntimeException("Not same content in " + + alias + " for " + oid); } } } CheckOid coid = new CheckOid(); - assertTrue(((X509CertImpl)ks.getCertificate("oid1")).getExtension(new ObjectIdentifier("1.2.3")).isCritical()); - assertTrue(!((X509CertImpl)ks.getCertificate("oid2")).getExtension(new ObjectIdentifier("1.2.3")).isCritical()); + assertTrue(((X509CertImpl)ks.getCertificate("oid1")) + .getExtension(new ObjectIdentifier("1.2.3")).isCritical()); + assertTrue(!((X509CertImpl)ks.getCertificate("oid2")) + .getExtension(new ObjectIdentifier("1.2.3")).isCritical()); coid.check(ks, "oid1", "1.2.3", new byte[]{1,2}); coid.check(ks, "oid2", "1.2.3", new byte[]{}); coid.check(ks, "oid12", "1.2.3", new byte[]{}); @@ -1163,7 +1588,8 @@ public class KeyToolTest { "-rfc -file test.req"); // printcertreq testOK("", "-printcertreq -file test.req"); - // issue: deny KU, change criticality of 1.2.3 and 1.2.4, change content of BC, add 2.3.4 + // issue: deny KU, change criticality of 1.2.3 and 1.2.4, + // change content of BC, add 2.3.4 testOK("", simple+"-gencert -alias ca -infile test.req -ext " + "honored=all,-KU,1.2.3:critical,1.2.4:non-critical " + "-ext BC=2 -ext 2.3.4=01020304 " + @@ -1210,64 +1636,100 @@ public class KeyToolTest { remove("x.jks"); testOK("", "-help"); - // 2. keytool -genkey -v -keysize 512 Enter "a" for the keystore password. Check error (password too short). Enter "password" for the keystore password. Hit 'return' for "first and last name", "organizational unit", "City", "State", and "Country Code". Type "yes" when they ask you if everything is correct. Type 'return' for new key password. - testOK("a\npassword\npassword\nMe\nHere\nNow\nPlace\nPlace\nUS\nyes\n\n", "-genkey -v -keysize 512 -keystore x.jks -storetype JKS"); + // 2. keytool -genkey -v -keysize 512 Enter "a" for the keystore + // password. Check error (password too short). Enter "password" for + // the keystore password. Hit 'return' for "first and last name", + // "organizational unit", "City", "State", and "Country Code". + // Type "yes" when they ask you if everything is correct. + // Type 'return' for new key password. + testOK("a\npassword\npassword\nMe\nHere\nNow\nPlace\nPlace\nUS\nyes\n\n", + "-genkey -v -keysize 512 -keystore x.jks -storetype JKS"); // 3. keytool -list -v -storepass password testOK("", "-list -v -storepass password -keystore x.jks -storetype JKS"); - // 4. keytool -list -v Type "a" for the keystore password. Check error (wrong keystore password). + // 4. keytool -list -v Type "a" for the keystore password. + // Check error (wrong keystore password). testFail("a\n", "-list -v -keystore x.jks -storetype JKS"); assertTrue(ex.indexOf("password was incorrect") != -1); - // 5. keytool -genkey -v -keysize 512 Enter "password" as the password. Check error (alias 'mykey' already exists). - testFail("password\n", "-genkey -v -keysize 512 -keystore x.jks -storetype JKS"); + // 5. keytool -genkey -v -keysize 512 Enter "password" as the password. + // Check error (alias 'mykey' already exists). + testFail("password\n", "-genkey -v -keysize 512" + + " -keystore x.jks -storetype JKS"); assertTrue(ex.indexOf("alias already exists") != -1); - // 6. keytool -genkey -v -keysize 512 -alias mykey2 -storepass password Hit 'return' for "first and last name", "organizational unit", "City", "State", and "Country Code". Type "yes" when they ask you if everything is correct. Type 'return' for new key password. - testOK("\n\n\n\n\n\nyes\n\n", "-genkey -v -keysize 512 -alias mykey2 -storepass password -keystore x.jks -storetype JKS"); + // 6. keytool -genkey -v -keysize 512 -alias mykey2 -storepass password + // Hit 'return' for "first and last name", "organizational unit", "City", + // "State", and "Country Code". Type "yes" when they ask you if + // everything is correct. Type 'return' for new key password. + testOK("\n\n\n\n\n\nyes\n\n", "-genkey -v -keysize 512 -alias mykey2" + + " -storepass password -keystore x.jks -storetype JKS"); // 7. keytool -list -v Type 'password' for the store password. testOK("password\n", "-list -v -keystore x.jks -storetype JKS"); - // 8. keytool -keypasswd -v -alias mykey2 -storepass password Type "a" for the new key password. Type "aaaaaa" for the new key password. Type "bbbbbb" when re-entering the new key password. Type "a" for the new key password. Check Error (too many failures). - testFail("a\naaaaaa\nbbbbbb\na\n", "-keypasswd -v -alias mykey2 -storepass password -keystore x.jks -storetype JKS"); + // 8. keytool -keypasswd -v -alias mykey2 -storepass password + // Type "a" for the new key password. Type "aaaaaa" for the new key + // password. Type "bbbbbb" when re-entering the new key password. + // Type "a" for the new key password. Check Error (too many failures). + testFail("a\naaaaaa\nbbbbbb\na\n", "-keypasswd -v -alias mykey2" + + " -storepass password -keystore x.jks -storetype JKS"); assertTrue(ex.indexOf("Too many failures - try later") != -1); - // 9. keytool -keypasswd -v -alias mykey2 -storepass password Type "aaaaaa" for the new key password. Type "aaaaaa" when re-entering the new key password. - testOK("aaaaaa\naaaaaa\n", "-keypasswd -v -alias mykey2 -storepass password -keystore x.jks -storetype JKS"); + // 9. keytool -keypasswd -v -alias mykey2 -storepass password + // Type "aaaaaa" for the new key password. Type "aaaaaa" + // when re-entering the new key password. + testOK("aaaaaa\naaaaaa\n", "-keypasswd -v -alias mykey2 " + + "-storepass password -keystore x.jks -storetype JKS"); // 10. keytool -selfcert -v -alias mykey -storepass password - testOK("", "-selfcert -v -alias mykey -storepass password -keystore x.jks -storetype JKS"); + testOK("", "-selfcert -v -alias mykey -storepass password " + + "-keystore x.jks -storetype JKS"); // 11. keytool -list -v -storepass password testOK("", "-list -v -storepass password -keystore x.jks -storetype JKS"); // 12. keytool -export -v -alias mykey -file cert -storepass password remove("cert"); - testOK("", "-export -v -alias mykey -file cert -storepass password -keystore x.jks -storetype JKS"); - // 13. keytool -import -v -file cert -storepass password Check error (Certificate reply and cert are the same) - testFail("", "-import -v -file cert -storepass password -keystore x.jks -storetype JKS"); - assertTrue(ex.indexOf("Certificate reply and certificate in keystore are identical") != -1); + testOK("", "-export -v -alias mykey -file cert -storepass password " + + "-keystore x.jks -storetype JKS"); + // 13. keytool -import -v -file cert -storepass password + // Check error (Certificate reply and cert are the same) + testFail("", "-import -v -file cert -storepass password" + + " -keystore x.jks -storetype JKS"); + assertTrue(ex.indexOf("Certificate reply and certificate" + + " in keystore are identical") != -1); // 14. keytool -printcert -file cert testOK("", "-printcert -file cert -keystore x.jks -storetype JKS"); remove("cert"); // 15. keytool -list -storepass password -provider sun.security.provider.Sun - testOK("", "-list -storepass password -provider sun.security.provider.Sun -keystore x.jks -storetype JKS"); + testOK("", "-list -storepass password" + + " -provider sun.security.provider.Sun" + + " -keystore x.jks -storetype JKS"); //Error tests - // 1. keytool -storepasswd -storepass password -new abc Check error (password too short) + // 1. keytool -storepasswd -storepass password -new abc + // Check error (password too short) testFail("", "-storepasswd -storepass password -new abc"); assertTrue(ex.indexOf("New password must be at least 6 characters") != -1); // Changed, no NONE needed now // 2. keytool -list -storetype PKCS11 Check error (-keystore must be NONE) //testFail("", "-list -storetype PKCS11"); //assertTrue(err.indexOf("keystore must be NONE") != -1); - // 3. keytool -storepasswd -storetype PKCS11 -keystore NONE Check error (unsupported operation) + // 3. keytool -storepasswd -storetype PKCS11 -keystore NONE + // Check error (unsupported operation) testFail("", "-storepasswd -storetype PKCS11 -keystore NONE"); assertTrue(ex.indexOf("UnsupportedOperationException") != -1); - // 4. keytool -keypasswd -storetype PKCS11 -keystore NONE Check error (unsupported operation) + // 4. keytool -keypasswd -storetype PKCS11 -keystore NONE + // Check error (unsupported operation) testFail("", "-keypasswd -storetype PKCS11 -keystore NONE"); assertTrue(ex.indexOf("UnsupportedOperationException") != -1); - // 5. keytool -list -protected -storepass password Check error (password can not be specified with -protected) - testFail("", "-list -protected -storepass password -keystore x.jks -storetype JKS"); + // 5. keytool -list -protected -storepass password + // Check error (password can not be specified with -protected) + testFail("", "-list -protected -storepass password " + + "-keystore x.jks -storetype JKS"); assertTrue(ex.indexOf("if -protected is specified, then") != -1); - // 6. keytool -keypasswd -protected -keypass password Check error (password can not be specified with -protected) - testFail("", "-keypasswd -protected -keypass password -keystore x.jks -storetype JKS"); + // 6. keytool -keypasswd -protected -keypass password + // Check error (password can not be specified with -protected) + testFail("", "-keypasswd -protected -keypass password " + + "-keystore x.jks -storetype JKS"); assertTrue(ex.indexOf("if -protected is specified, then") != -1); - // 7. keytool -keypasswd -protected -new password Check error (password can not be specified with -protected) - testFail("", "-keypasswd -protected -new password -keystore x.jks -storetype JKS"); + // 7. keytool -keypasswd -protected -new password + // Check error (password can not be specified with -protected) + testFail("", "-keypasswd -protected -new password " + + "-keystore x.jks -storetype JKS"); assertTrue(ex.indexOf("if -protected is specified, then") != -1); remove("x.jks"); } @@ -1277,14 +1739,19 @@ public class KeyToolTest { // 1. sccs edit cert8.db key3.db //Runtime.getRuntime().exec("/usr/ccs/bin/sccs edit cert8.db key3.db"); - testOK("", p11Arg + "-storepass test12 -genkey -alias genkey -dname cn=genkey -keysize 512 -keyalg rsa"); + testOK("", p11Arg + ("-storepass test12 -genkey -alias genkey" + + " -dname cn=genkey -keysize 512 -keyalg rsa")); testOK("", p11Arg + "-storepass test12 -list"); testOK("", p11Arg + "-storepass test12 -list -alias genkey"); - testOK("", p11Arg + "-storepass test12 -certreq -alias genkey -file genkey.certreq"); - testOK("", p11Arg + "-storepass test12 -export -alias genkey -file genkey.cert"); + testOK("", p11Arg + + "-storepass test12 -certreq -alias genkey -file genkey.certreq"); + testOK("", p11Arg + + "-storepass test12 -export -alias genkey -file genkey.cert"); testOK("", "-printcert -file genkey.cert"); - testOK("", p11Arg + "-storepass test12 -selfcert -alias genkey -dname cn=selfCert"); - testOK("", p11Arg + "-storepass test12 -list -alias genkey -v"); + testOK("", p11Arg + + "-storepass test12 -selfcert -alias genkey -dname cn=selfCert"); + testOK("", p11Arg + + "-storepass test12 -list -alias genkey -v"); assertTrue(out.indexOf("Owner: CN=selfCert") != -1); //(check that cert subject DN is [cn=selfCert]) testOK("", p11Arg + "-storepass test12 -delete -alias genkey"); @@ -1301,7 +1768,8 @@ public class KeyToolTest { void sszzTest() throws Exception { testAnyway("", NSS_P11_ARG+"-delete -alias nss -storepass test12"); testAnyway("", NZZ_P11_ARG+"-delete -alias nss -storepass test12"); - testOK("", NSS_P11_ARG+"-genkeypair -dname CN=NSS -alias nss -storepass test12"); + testOK("", NSS_P11_ARG+"-genkeypair -dname CN=NSS " + + "-alias nss -storepass test12"); testOK("", NSS_SRC_P11_ARG + NZZ_P11_ARG + "-importkeystore -srcstorepass test12 -deststorepass test12"); testAnyway("", NSS_P11_ARG+"-delete -alias nss -storepass test12"); @@ -1339,11 +1807,13 @@ public class KeyToolTest { // FAIL: // 1. we still don't have srcprovidername yet // 2. cannot store privatekey into NSS keystore - // java.security.KeyStoreException: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_TEMPLATE_INCOMPLETE. + // java.security.KeyStoreException: sun.security.pkcs11 + // .wrapper.PKCS11Exception: CKR_TEMPLATE_INCOMPLETE. //t.testPKCS11ImportKeyStore(); t.i18nPKCS11Test(); - //FAIL: currently PKCS11-NSS does not support 2 NSS KeyStores to be loaded at the same time + //FAIL: currently PKCS11-NSS does not support + // 2 NSS KeyStores to be loaded at the same time //t.sszzTest(); } From 79240eab9ba93609c3eddb606e0e4f295de7cab4 Mon Sep 17 00:00:00 2001 From: Sean Coffey Date: Thu, 26 Feb 2015 09:36:30 +0000 Subject: [PATCH 25/29] 8071447: IBM1166 Locale Request for Kazakh characters Reviewed-by: sherman --- jdk/make/data/charsetmapping/IBM1166.c2b | 1 + jdk/make/data/charsetmapping/IBM1166.map | 256 ++++++++++++++++++ jdk/make/data/charsetmapping/IBM1166.nr | 1 + jdk/make/data/charsetmapping/charsets | 10 + jdk/make/data/charsetmapping/list_old | 1 + .../charset/Charset/RegisteredCharsets.java | 12 +- .../nio/charset/RemovingSunIO/SunioAlias.java | 6 + jdk/test/sun/nio/cs/CheckHistoricalNames.java | 1 + 8 files changed, 287 insertions(+), 1 deletion(-) create mode 100644 jdk/make/data/charsetmapping/IBM1166.c2b create mode 100644 jdk/make/data/charsetmapping/IBM1166.map create mode 100644 jdk/make/data/charsetmapping/IBM1166.nr diff --git a/jdk/make/data/charsetmapping/IBM1166.c2b b/jdk/make/data/charsetmapping/IBM1166.c2b new file mode 100644 index 00000000000..6cb38028124 --- /dev/null +++ b/jdk/make/data/charsetmapping/IBM1166.c2b @@ -0,0 +1 @@ +0x15 U+0085 diff --git a/jdk/make/data/charsetmapping/IBM1166.map b/jdk/make/data/charsetmapping/IBM1166.map new file mode 100644 index 00000000000..daaf83e8857 --- /dev/null +++ b/jdk/make/data/charsetmapping/IBM1166.map @@ -0,0 +1,256 @@ +0x00 U+0000 +0x01 U+0001 +0x02 U+0002 +0x03 U+0003 +0x04 U+009c +0x05 U+0009 +0x06 U+0086 +0x07 U+007f +0x08 U+0097 +0x09 U+008d +0x0a U+008e +0x0b U+000b +0x0c U+000c +0x0d U+000d +0x0e U+000e +0x0f U+000f +0x10 U+0010 +0x11 U+0011 +0x12 U+0012 +0x13 U+0013 +0x14 U+009d +0x15 U+000a +0x16 U+0008 +0x17 U+0087 +0x18 U+0018 +0x19 U+0019 +0x1a U+0092 +0x1b U+008f +0x1c U+001c +0x1d U+001d +0x1e U+001e +0x1f U+001f +0x20 U+0080 +0x21 U+0081 +0x22 U+0082 +0x23 U+0083 +0x24 U+0084 +0x25 U+000a +0x26 U+0017 +0x27 U+001b +0x28 U+0088 +0x29 U+0089 +0x2a U+008a +0x2b U+008b +0x2c U+008c +0x2d U+0005 +0x2e U+0006 +0x2f U+0007 +0x30 U+0090 +0x31 U+0091 +0x32 U+0016 +0x33 U+0093 +0x34 U+0094 +0x35 U+0095 +0x36 U+0096 +0x37 U+0004 +0x38 U+0098 +0x39 U+0099 +0x3a U+009a +0x3b U+009b +0x3c U+0014 +0x3d U+0015 +0x3e U+009e +0x3f U+001a +0x40 U+0020 +0x41 U+00a0 +0x42 U+04d9 +0x43 U+0493 +0x44 U+0451 +0x45 U+0454 +0x46 U+0455 +0x47 U+0456 +0x48 U+049b +0x49 U+0458 +0x4a U+005b +0x4b U+002e +0x4c U+003c +0x4d U+0028 +0x4e U+002b +0x4f U+0021 +0x50 U+0026 +0x51 U+04a3 +0x52 U+04e9 +0x53 U+04b1 +0x54 U+04af +0x55 U+045e +0x56 U+04bb +0x57 U+042a +0x58 U+2116 +0x59 U+04d8 +0x5a U+005d +0x5b U+0024 +0x5c U+002a +0x5d U+0029 +0x5e U+003b +0x5f U+005e +0x60 U+002d +0x61 U+002f +0x62 U+0492 +0x63 U+0401 +0x64 U+0404 +0x65 U+0405 +0x66 U+0406 +0x67 U+049a +0x68 U+0408 +0x69 U+04a2 +0x6a U+007c +0x6b U+002c +0x6c U+0025 +0x6d U+005f +0x6e U+003e +0x6f U+003f +0x70 U+04e8 +0x71 U+04b0 +0x72 U+04ae +0x73 U+00ad +0x74 U+040e +0x75 U+04ba +0x76 U+044e +0x77 U+0430 +0x78 U+0431 +0x79 U+0060 +0x7a U+003a +0x7b U+0023 +0x7c U+0040 +0x7d U+0027 +0x7e U+003d +0x7f U+0022 +0x80 U+0446 +0x81 U+0061 +0x82 U+0062 +0x83 U+0063 +0x84 U+0064 +0x85 U+0065 +0x86 U+0066 +0x87 U+0067 +0x88 U+0068 +0x89 U+0069 +0x8a U+0434 +0x8b U+0435 +0x8c U+0444 +0x8d U+0433 +0x8e U+0445 +0x8f U+0438 +0x90 U+0439 +0x91 U+006a +0x92 U+006b +0x93 U+006c +0x94 U+006d +0x95 U+006e +0x96 U+006f +0x97 U+0070 +0x98 U+0071 +0x99 U+0072 +0x9a U+043a +0x9b U+043b +0x9c U+043c +0x9d U+043d +0x9e U+043e +0x9f U+043f +0xa0 U+044f +0xa1 U+007e +0xa2 U+0073 +0xa3 U+0074 +0xa4 U+0075 +0xa5 U+0076 +0xa6 U+0077 +0xa7 U+0078 +0xa8 U+0079 +0xa9 U+007a +0xaa U+0440 +0xab U+0441 +0xac U+0442 +0xad U+0443 +0xae U+0436 +0xaf U+0432 +0xb0 U+044c +0xb1 U+044b +0xb2 U+0437 +0xb3 U+0448 +0xb4 U+044d +0xb5 U+0449 +0xb6 U+0447 +0xb7 U+044a +0xb8 U+042e +0xb9 U+0410 +0xba U+0411 +0xbb U+0426 +0xbc U+0414 +0xbd U+0415 +0xbe U+0424 +0xbf U+0413 +0xc0 U+007b +0xc1 U+0041 +0xc2 U+0042 +0xc3 U+0043 +0xc4 U+0044 +0xc5 U+0045 +0xc6 U+0046 +0xc7 U+0047 +0xc8 U+0048 +0xc9 U+0049 +0xca U+0425 +0xcb U+0418 +0xcc U+0419 +0xcd U+041a +0xce U+041b +0xcf U+041c +0xd0 U+007d +0xd1 U+004a +0xd2 U+004b +0xd3 U+004c +0xd4 U+004d +0xd5 U+004e +0xd6 U+004f +0xd7 U+0050 +0xd8 U+0051 +0xd9 U+0052 +0xda U+041d +0xdb U+041e +0xdc U+041f +0xdd U+042f +0xde U+0420 +0xdf U+0421 +0xe0 U+005c +0xe1 U+20ac +0xe2 U+0053 +0xe3 U+0054 +0xe4 U+0055 +0xe5 U+0056 +0xe6 U+0057 +0xe7 U+0058 +0xe8 U+0059 +0xe9 U+005a +0xea U+0422 +0xeb U+0423 +0xec U+0416 +0xed U+0412 +0xee U+042c +0xef U+042b +0xf0 U+0030 +0xf1 U+0031 +0xf2 U+0032 +0xf3 U+0033 +0xf4 U+0034 +0xf5 U+0035 +0xf6 U+0036 +0xf7 U+0037 +0xf8 U+0038 +0xf9 U+0039 +0xfa U+0417 +0xfb U+0428 +0xfc U+042d +0xfd U+0429 +0xfe U+0427 +0xff U+009f diff --git a/jdk/make/data/charsetmapping/IBM1166.nr b/jdk/make/data/charsetmapping/IBM1166.nr new file mode 100644 index 00000000000..675451906d4 --- /dev/null +++ b/jdk/make/data/charsetmapping/IBM1166.nr @@ -0,0 +1 @@ +0x25 U+000a diff --git a/jdk/make/data/charsetmapping/charsets b/jdk/make/data/charsetmapping/charsets index 09d06c5a335..ff6584b2cfb 100644 --- a/jdk/make/data/charsetmapping/charsets +++ b/jdk/make/data/charsetmapping/charsets @@ -1660,6 +1660,16 @@ charset IBM290 IBM290 alias EBCDIC-JP-kana alias 290 +charset x-IBM1166 IBM1166 + package sun.nio.cs.ext + type sbcs + hisname Cp1166 + ascii false + alias cp1166 + alias ibm1166 + alias ibm-1166 + alias 1166 + charset x-IBM300 IBM300 package sun.nio.cs.ext type dbcsonly diff --git a/jdk/make/data/charsetmapping/list_old b/jdk/make/data/charsetmapping/list_old index ca03b40921b..51a5941f4a0 100644 --- a/jdk/make/data/charsetmapping/list_old +++ b/jdk/make/data/charsetmapping/list_old @@ -57,6 +57,7 @@ IBM1146 IBM01146 Cp1146 false sun.nio.cs.ext IBM1147 IBM01147 Cp1147 false sun.nio.cs.ext IBM1148 IBM01148 Cp1148 false sun.nio.cs.ext IBM1149 IBM01149 Cp1149 false sun.nio.cs.ext +IBM1166 x-IBM1166 Cp1166 false sun.nio.cs.ext IBM273 IBM273 Cp273 false sun.nio.cs.ext IBM277 IBM277 Cp277 false sun.nio.cs.ext IBM278 IBM278 Cp278 false sun.nio.cs.ext diff --git a/jdk/test/java/nio/charset/Charset/RegisteredCharsets.java b/jdk/test/java/nio/charset/Charset/RegisteredCharsets.java index d942369ad32..4fd3dbb3228 100644 --- a/jdk/test/java/nio/charset/Charset/RegisteredCharsets.java +++ b/jdk/test/java/nio/charset/Charset/RegisteredCharsets.java @@ -22,7 +22,8 @@ */ /* @test - * @bug 4473201 4696726 4652234 4482298 4784385 4966197 4267354 5015668 6911753 + * @bug 4473201 4696726 4652234 4482298 4784385 4966197 4267354 5015668 + 6911753 8071447 * @summary Check that registered charsets are actually registered */ @@ -135,6 +136,7 @@ public class RegisteredCharsets { "x-IBM1122", "x-IBM1123", "x-IBM1124", + "x-IBM1166", "x-IBM875", "x-IBM921", "x-IBM922", @@ -863,6 +865,14 @@ public class RegisteredCharsets { "1124" } ); + aliasCheck("x-IBM1166" , + new String[] { + "cp1166", // JDK historical + "ibm1166", + "ibm-1166", + "1166" + } ); + aliasCheck("IBM273" , new String[] { "cp273", // JDK historical diff --git a/jdk/test/java/nio/charset/RemovingSunIO/SunioAlias.java b/jdk/test/java/nio/charset/RemovingSunIO/SunioAlias.java index af527fc1572..fe9c3598acf 100644 --- a/jdk/test/java/nio/charset/RemovingSunIO/SunioAlias.java +++ b/jdk/test/java/nio/charset/RemovingSunIO/SunioAlias.java @@ -674,6 +674,12 @@ public class SunioAlias { aliasTable.put("cp1124", "Cp1124"); aliasTable.put("1124", "Cp1124"); + // MIBenum: ???? + aliasTable.put("ibm1166", "Cp1166"); + aliasTable.put("ibm-1166", "Cp1166"); + aliasTable.put("cp1166", "Cp1166"); + aliasTable.put("1166", "Cp1166"); + // MIBenum: ???? aliasTable.put("ibm1381", "Cp1381"); /* MDA */ aliasTable.put("ibm-1381", "Cp1381"); /* MDA */ diff --git a/jdk/test/sun/nio/cs/CheckHistoricalNames.java b/jdk/test/sun/nio/cs/CheckHistoricalNames.java index 39e1ecd144c..0b1ee60f301 100644 --- a/jdk/test/sun/nio/cs/CheckHistoricalNames.java +++ b/jdk/test/sun/nio/cs/CheckHistoricalNames.java @@ -196,6 +196,7 @@ public class CheckHistoricalNames { checkMappedName("IBM1122", "Cp1122"); checkMappedName("IBM1123", "Cp1123"); checkMappedName("IBM1124", "Cp1124"); + checkMappedName("IBM1166", "Cp1166"); checkMappedName("IBM01140", "Cp1140"); checkMappedName("IBM01141", "Cp1141"); checkMappedName("IBM01142", "Cp1142"); From a929976abd6a3f547be2d6d742f1ec18a798b8b8 Mon Sep 17 00:00:00 2001 From: Vinnie Ryan Date: Thu, 26 Feb 2015 16:29:49 +0000 Subject: [PATCH 26/29] 8073955: Update java.security.debug help text to reflect recent enhancements for debugging Reviewed-by: mullan --- .../java.base/share/classes/sun/security/util/Debug.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/jdk/src/java.base/share/classes/sun/security/util/Debug.java b/jdk/src/java.base/share/classes/sun/security/util/Debug.java index 8e2bb9e2874..8174438c455 100644 --- a/jdk/src/java.base/share/classes/sun/security/util/Debug.java +++ b/jdk/src/java.base/share/classes/sun/security/util/Debug.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -80,11 +80,13 @@ public class Debug { System.err.println("jar jar verification"); System.err.println("logincontext login context results"); System.err.println("jca JCA engine class debugging"); + System.err.println("keystore KeyStore debugging"); System.err.println("policy loading and granting"); System.err.println("provider security provider debugging"); System.err.println("pkcs11 PKCS11 session manager debugging"); System.err.println("pkcs11keystore"); System.err.println(" PKCS11 KeyStore debugging"); + System.err.println("pkcs12 PKCS12 KeyStore debugging"); System.err.println("sunpkcs11 SunPKCS11 provider debugging"); System.err.println("scl permissions SecureClassLoader assigns"); System.err.println("ts timestamping"); @@ -114,6 +116,10 @@ public class Debug { System.err.println(" KeyPairGenerator, KeyStore, Mac,"); System.err.println(" MessageDigest, SecureRandom, Signature."); System.err.println(); + System.err.println("The following can be used with certpath:"); + System.err.println(); + System.err.println("ocsp dump the OCSP protocol exchanges"); + System.err.println(); System.err.println("Note: Separate multiple options with a comma"); System.exit(0); } From 7f950ef63df0447625227f8b203b90940e92055e Mon Sep 17 00:00:00 2001 From: Xueming Shen Date: Thu, 26 Feb 2015 14:40:43 -0800 Subject: [PATCH 27/29] 8073924: Update test/java/nio/charset/Charset/NIOCharsetAvailability.java to work with module system To use module's runtime filesystem to iterate the class files Reviewed-by: alanb --- .../Charset/NIOCharsetAvailabilityTest.java | 208 ++++-------------- 1 file changed, 48 insertions(+), 160 deletions(-) diff --git a/jdk/test/java/nio/charset/Charset/NIOCharsetAvailabilityTest.java b/jdk/test/java/nio/charset/Charset/NIOCharsetAvailabilityTest.java index 9b3e3a2597a..f2a1e05e608 100644 --- a/jdk/test/java/nio/charset/Charset/NIOCharsetAvailabilityTest.java +++ b/jdk/test/java/nio/charset/Charset/NIOCharsetAvailabilityTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -23,41 +23,63 @@ /* * @test - * @bug 4777124 6920545 6911753 + * @bug 4777124 6920545 6911753 8073924 * @summary Verify that all Charset subclasses are available through the API */ -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; +import java.net.URI; import java.nio.charset.Charset; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.Collection; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.HashSet; -import java.util.Iterator; import java.util.Set; -import java.util.Vector; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - +import java.util.stream.Collectors; +import java.util.stream.Stream; public class NIOCharsetAvailabilityTest { public static void main(String[] args) throws Exception { + // build the set of all Charset subclasses in the // two known charset implementation packages - Set charsets = new HashSet(); - addCharsets(charsets, "sun.nio.cs"); - addCharsets(charsets, "sun.nio.cs.ext"); - + FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); + Set charsets = + Stream.concat(Files.walk(fs.getPath("/java.base/sun/nio/cs/")), + Files.walk(fs.getPath("/jdk.charsets/sun/nio/cs/ext/"))) + .map( p -> p.subpath(1, p.getNameCount()).toString()) + .filter( s -> s.indexOf("$") == -1 && s.endsWith(".class")) + .map( s -> { + try { + return Class.forName(s.substring(0, s.length() - 6) + .replace('/', '.')); + } catch (Exception x) { + throw new RuntimeException(x); + } + }) + .filter( clz -> { + Class superclazz = clz.getSuperclass(); + while (superclazz != null && !superclazz.equals(Object.class)) { + if (superclazz.equals(Charset.class)) { + return true; + } else { + superclazz = superclazz.getSuperclass(); + } + } + return false; + }) + .collect(Collectors.toCollection(HashSet::new)); // remove the charsets that the API says are available - Collection availableCharsets = Charset.availableCharsets().values(); - Iterator iter = availableCharsets.iterator(); - while (iter.hasNext()) { - charsets.remove(((Charset) iter.next()).getClass()); - } + Charset.availableCharsets() + .values() + .stream() + .forEach(cs -> { + if (!charsets.contains(cs.getClass())) { + System.out.println(" missing -> " + cs.getClass()); + } + charsets.remove(cs.getClass()); + }); // remove the known pseudo-charsets that serve only to implement // other charsets, but shouldn't be known to the public @@ -76,146 +98,12 @@ public class NIOCharsetAvailabilityTest { charsets.remove(Class.forName("sun.nio.cs.JIS_X_0208_Solaris")); charsets.remove(Class.forName("sun.nio.cs.JIS_X_0212_Solaris")); } - // report the charsets that are implemented but not available - iter = charsets.iterator(); - while (iter.hasNext()) { - System.out.println("Unused Charset subclass: " + ((Class) iter.next()).getName()); - } if (charsets.size() > 0) { + charsets.stream() + .forEach( clz -> + System.out.println("Unused Charset subclass: " + clz)); throw new RuntimeException(); } } - - private static Vector classPathSegments = new Vector(); - - private static void addCharsets(Set charsets, final String packageName) - throws Exception { - - String classPath = AccessController.doPrivileged( - (PrivilegedAction)() -> System.getProperty("sun.boot.class.path")); - String s = AccessController.doPrivileged( - (PrivilegedAction)() -> System.getProperty("java.class.path")); - - // Search combined system and application class path - if (s != null && s.length() != 0) { - classPath += File.pathSeparator + s; - } - while (classPath != null && classPath.length() != 0) { - int i = classPath.lastIndexOf(java.io.File.pathSeparatorChar); - String dir = classPath.substring(i + 1); - if (i == -1) { - classPath = null; - } else { - classPath = classPath.substring(0, i); - } - classPathSegments.insertElementAt(dir, 0); - } - - String[] classList = (String[]) - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - return getClassList(packageName, ""); - } - }); - - for (int i = 0; i < classList.length; i++) { - try { - Class clazz = Class.forName(packageName + "." + classList[i]); - Class superclazz = clazz.getSuperclass(); - while (superclazz != null && !superclazz.equals(Object.class)) { - if (superclazz.equals(Charset.class)) { - charsets.add(clazz); - break; - } else { - superclazz = superclazz.getSuperclass(); - } - } - } catch (ClassNotFoundException e) { - } - } - } - - private static final char ZIPSEPARATOR = '/'; - - /** - * Walk through CLASSPATH and find class list from a package. - * The class names start with prefix string - * @param package name, class name prefix - * @return class list in an array of String - */ - private static String[] getClassList(String pkgName, String prefix) { - Vector listBuffer = new Vector(); - String packagePath = pkgName.replace('.', File.separatorChar) - + File.separatorChar; - String zipPackagePath = pkgName.replace('.', ZIPSEPARATOR) - + ZIPSEPARATOR; - for (int i = 0; i < classPathSegments.size(); i++){ - String onePath = (String) classPathSegments.elementAt(i); - File f = new File(onePath); - if (!f.exists()) - continue; - if (f.isFile()) - scanFile(f, zipPackagePath, listBuffer, prefix); - else if (f.isDirectory()) { - String fullPath; - if (onePath.endsWith(File.separator)) - fullPath = onePath + packagePath; - else - fullPath = onePath + File.separatorChar + packagePath; - File dir = new File(fullPath); - if (dir.exists() && dir.isDirectory()) - scanDir(dir, listBuffer, prefix); - } - } - String[] classNames = new String[listBuffer.size()]; - listBuffer.copyInto(classNames); - return classNames; - } - - private static void addClass (String className, Vector listBuffer, String prefix) { - if (className != null && className.startsWith(prefix) - && !listBuffer.contains(className)) - listBuffer.addElement(className); - } - - private static String midString(String str, String pre, String suf) { - String midStr; - if (str.startsWith(pre) && str.endsWith(suf)) - midStr = str.substring(pre.length(), str.length() - suf.length()); - else - midStr = null; - return midStr; - } - - private static void scanDir(File dir, Vector listBuffer, String prefix) { - String[] fileList = dir.list(); - for (int i = 0; i < fileList.length; i++) { - addClass(midString(fileList[i], "", ".class"), listBuffer, prefix); - } - } - - private static void scanFile(File f, String packagePath, Vector listBuffer, - String prefix) { - try { - ZipInputStream zipFile = new ZipInputStream(new FileInputStream(f)); - ZipEntry entry; - while ((entry = zipFile.getNextEntry()) != null) { - String eName = entry.getName(); - if (eName.startsWith(packagePath)) { - if (eName.endsWith(".class")) { - addClass(midString(eName, packagePath, ".class"), - listBuffer, prefix); - } - } - } - } catch (FileNotFoundException e) { - System.out.println("file not found:" + e); - } catch (IOException e) { - System.out.println("file IO Exception:" + e); - } catch (Exception e) { - System.out.println("Exception:" + e); - } - } } From ff45a0b5b0abc73a4b8bc15a67ed513ddf919c27 Mon Sep 17 00:00:00 2001 From: Lev Priima Date: Thu, 26 Feb 2015 18:50:02 -0500 Subject: [PATCH 28/29] 8073354: TimSortStackSize2.java: test cleanup: make test run with single argument Reviewed-by: dholmes --- .../java/util/Arrays/TimSortStackSize2.java | 107 +++++++++--------- 1 file changed, 52 insertions(+), 55 deletions(-) diff --git a/jdk/test/java/util/Arrays/TimSortStackSize2.java b/jdk/test/java/util/Arrays/TimSortStackSize2.java index c2971b14a6e..a456c883000 100644 --- a/jdk/test/java/util/Arrays/TimSortStackSize2.java +++ b/jdk/test/java/util/Arrays/TimSortStackSize2.java @@ -24,63 +24,59 @@ /* * @test * @bug 8072909 - * @run main/othervm -Xmx385m TimSortStackSize2 67108864 - * not for regular execution on all platforms: + * @run main/othervm -Xms385m TimSortStackSize2 67108864 + * @summary Test TimSort stack size on big arrays + * big tests not for regular execution on all platforms: * run main/othervm -Xmx8g TimSortStackSize2 1073741824 * run main/othervm -Xmx16g TimSortStackSize2 2147483644 - * @summary Test TimSort stack size on big arrays */ import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; +import java.util.function.Consumer; public class TimSortStackSize2 { public static void main(String[] args) { int lengthOfTest = Integer.parseInt(args[0]); - boolean passed = true; - try { - Integer [] a = new TimSortStackSize2(lengthOfTest).createArray(); - long begin = System.nanoTime(); - Arrays.sort(a, new Comparator() { - @SuppressWarnings("unchecked") - public int compare(Object first, Object second) { - return ((Comparable)first).compareTo(second); - } - }); - long end = System.nanoTime(); - System.out.println("TimSort: " + (end - begin)); - a = null; - } catch (ArrayIndexOutOfBoundsException e){ - System.out.println("TimSort broken:"); - e.printStackTrace(); - passed = false; - } - - try { - Integer [] a = new TimSortStackSize2(lengthOfTest).createArray(); - long begin = System.nanoTime(); - Arrays.sort(a); - long end = System.nanoTime(); - System.out.println("ComparableTimSort: " + (end - begin)); - a = null; - } catch (ArrayIndexOutOfBoundsException e){ - System.out.println("ComparableTimSort broken:"); - e.printStackTrace(); - passed = false; - } + boolean passed = doTest("TimSort", lengthOfTest, + (Integer [] a) -> Arrays.sort(a)); + passed = doTest("ComparableTimSort", lengthOfTest, (Integer [] a) -> + Arrays.sort(a, (Object first, Object second) -> { + return ((Comparable)first).compareTo(second); + })) + && passed; if ( !passed ){ throw new RuntimeException(); } } + private static boolean doTest(final String msg, final int lengthOfTest, + final Consumer c){ + Integer [] a = null; + try { + a = new TimSortStackSize2(lengthOfTest).createArray(); + long begin = System.nanoTime(); + c.accept(a); + long end = System.nanoTime(); + System.out.println(msg + " OK. Time: " + (end - begin) + "ns"); + } catch (ArrayIndexOutOfBoundsException e){ + System.out.println(msg + " broken:"); + e.printStackTrace(); + return false; + } finally { + a = null; + } + return true; + } + private static final int MIN_MERGE = 32; private final int minRun; private final int length; private final List runs = new ArrayList(); - public TimSortStackSize2(int len) { + public TimSortStackSize2(final int len) { this.length = len; minRun = minRunLength(len); fillRunsJDKWorstCase(); @@ -106,24 +102,24 @@ public class TimSortStackSize2 { * @param X The sum of the sequence that should be added to runs. */ private void generateJDKWrongElem(long X) { - for(long newTotal; X >= 2*minRun+1; X = newTotal) { + for(long newTotal; X >= 2 * minRun + 1; X = newTotal) { //Default strategy - newTotal = X/2 + 1; + newTotal = X / 2 + 1; //Specialized strategies - if(3*minRun+3 <= X && X <= 4*minRun+1) { + if(3 * minRun + 3 <= X && X <= 4*minRun+1) { // add x_1=MIN+1, x_2=MIN, x_3=X-newTotal to runs - newTotal = 2*minRun+1; - } else if(5*minRun+5 <= X && X <= 6*minRun+5) { + newTotal = 2 * minRun + 1; + } else if (5 * minRun + 5 <= X && X <= 6 * minRun + 5) { // add x_1=MIN+1, x_2=MIN, x_3=MIN+2, x_4=X-newTotal to runs - newTotal = 3*minRun+3; - } else if(8*minRun+9 <= X && X <= 10*minRun+9) { + newTotal = 3 * minRun + 3; + } else if (8 * minRun + 9 <= X && X <= 10 * minRun + 9) { // add x_1=MIN+1, x_2=MIN, x_3=MIN+2, x_4=2MIN+2, x_5=X-newTotal to runs - newTotal = 5*minRun+5; - } else if(13*minRun+15 <= X && X <= 16*minRun+17) { + newTotal = 5 * minRun + 5; + } else if (13 * minRun + 15 <= X && X <= 16 * minRun + 17) { // add x_1=MIN+1, x_2=MIN, x_3=MIN+2, x_4=2MIN+2, x_5=3MIN+4, x_6=X-newTotal to runs - newTotal = 8*minRun+9; + newTotal = 8 * minRun + 9; } - runs.add(0, X-newTotal); + runs.add(0, X - newTotal); } runs.add(0, X); } @@ -144,10 +140,10 @@ public class TimSortStackSize2 { long Y = minRun + 4; long X = minRun; - while(runningTotal+Y+X <= length) { + while (runningTotal + Y + X <= length) { runningTotal += X + Y; generateJDKWrongElem(X); - runs.add(0,Y); + runs.add(0, Y); // X_{i+1} = Y_i + x_{i,1} + 1, since runs.get(1) = x_{i,1} X = Y + runs.get(1) + 1; @@ -156,21 +152,22 @@ public class TimSortStackSize2 { Y += X + 1; } - if(runningTotal + X <= length) { + if (runningTotal + X <= length) { runningTotal += X; generateJDKWrongElem(X); } - runs.add(length-runningTotal); + runs.add(length - runningTotal); } - private Integer[] createArray() { - Integer[] a = new Integer[length]; + private Integer [] createArray() { + Integer [] a = new Integer[length]; Arrays.fill(a, 0); int endRun = -1; - for(long len : runs) - a[endRun+=len] = 1; - a[length-1]=0; + for (long len : runs) { + a[endRun += len] = 1; + } + a[length - 1] = 0; return a; } From 8efc09a66af35692e076f50adda3f46e93b40f07 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Thu, 26 Feb 2015 18:02:49 -0800 Subject: [PATCH 29/29] 8073952: Spec of j.l.r.Method.toString/toGenericString need to be clarified Reviewed-by: lancea --- .../share/classes/java/lang/reflect/Constructor.java | 6 ++++-- .../java.base/share/classes/java/lang/reflect/Method.java | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/lang/reflect/Constructor.java b/jdk/src/java.base/share/classes/java/lang/reflect/Constructor.java index b86e1a4eae0..97e66362904 100644 --- a/jdk/src/java.base/share/classes/java/lang/reflect/Constructor.java +++ b/jdk/src/java.base/share/classes/java/lang/reflect/Constructor.java @@ -296,7 +296,8 @@ public final class Constructor extends Executable { * constructor has default (package) access. * * @return a string describing this {@code Constructor} - * @jls 8.8.3. Constructor Modifiers + * @jls 8.8.3 Constructor Modifiers + * @jls 8.9.2 Enum Body Declarations */ public String toString() { return sharedToString(Modifier.constructorModifiers(), @@ -342,7 +343,8 @@ public final class Constructor extends Executable { * include type parameters * * @since 1.5 - * @jls 8.8.3. Constructor Modifiers + * @jls 8.8.3 Constructor Modifiers + * @jls 8.9.2 Enum Body Declarations */ @Override public String toGenericString() { diff --git a/jdk/src/java.base/share/classes/java/lang/reflect/Method.java b/jdk/src/java.base/share/classes/java/lang/reflect/Method.java index ddf0f3888ab..27bbd91a3ac 100644 --- a/jdk/src/java.base/share/classes/java/lang/reflect/Method.java +++ b/jdk/src/java.base/share/classes/java/lang/reflect/Method.java @@ -356,6 +356,8 @@ public final class Method extends Executable { * @return a string describing this {@code Method} * * @jls 8.4.3 Method Modifiers + * @jls 9.4 Method Declarations + * @jls 9.6.1 Annotation Type Elements */ public String toString() { return sharedToString(Modifier.methodModifiers(), @@ -409,6 +411,8 @@ public final class Method extends Executable { * @since 1.5 * * @jls 8.4.3 Method Modifiers + * @jls 9.4 Method Declarations + * @jls 9.6.1 Annotation Type Elements */ @Override public String toGenericString() {