# HG changeset patch # User amurillo # Date 1474048641 25200 # Node ID 9fb8c8e7528ed33cfd46f6666303e7c19b0dbc7a # Parent 805dd7bef81f8c6a1fc243f55223f367706036aa# Parent 57810b6b669eba9fa8fedef1e57ba59e3c0aa1da Merge diff -r 805dd7bef81f -r 9fb8c8e7528e jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java --- a/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java Thu Sep 15 21:08:59 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java Fri Sep 16 10:57:21 2016 -0700 @@ -71,6 +71,7 @@ // These flags must match the values maintained in the VM @Native private static final int DEFAULT_MODE = 0x0; @Native private static final int FILL_CLASS_REFS_ONLY = 0x2; + @Native private static final int GET_CALLER_CLASS = 0x4; @Native private static final int SHOW_HIDDEN_FRAMES = 0x20; // LambdaForms are hidden by the VM @Native private static final int FILL_LIVE_STACK_FRAMES = 0x100; /* @@ -614,9 +615,7 @@ private Class caller; CallerClassFinder(StackWalker walker) { - super(walker, FILL_CLASS_REFS_ONLY); - assert (mode & FILL_CLASS_REFS_ONLY) == FILL_CLASS_REFS_ONLY - : "mode should contain FILL_CLASS_REFS_ONLY"; + super(walker, FILL_CLASS_REFS_ONLY|GET_CALLER_CLASS); } final class ClassBuffer extends FrameBuffer> { diff -r 805dd7bef81f -r 9fb8c8e7528e jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java --- a/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java Thu Sep 15 21:08:59 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java Fri Sep 16 10:57:21 2016 -0700 @@ -1603,11 +1603,50 @@ return weakCompareAndSwapShort(o, offset, c2s(expected), c2s(x)); } + /** + * The JVM converts integral values to boolean values using two + * different conventions, byte testing against zero and truncation + * to least-significant bit. + * + *

The JNI documents specify that, at least for returning + * values from native methods, a Java boolean value is converted + * to the value-set 0..1 by first truncating to a byte (0..255 or + * maybe -128..127) and then testing against zero. Thus, Java + * booleans in non-Java data structures are by convention + * represented as 8-bit containers containing either zero (for + * false) or any non-zero value (for true). + * + *

Java booleans in the heap are also stored in bytes, but are + * strongly normalized to the value-set 0..1 (i.e., they are + * truncated to the least-significant bit). + * + *

The main reason for having different conventions for + * conversion is performance: Truncation to the least-significant + * bit can be usually implemented with fewer (machine) + * instructions than byte testing against zero. + * + *

A number of Unsafe methods load boolean values from the heap + * as bytes. Unsafe converts those values according to the JNI + * rules (i.e, using the "testing against zero" convention). The + * method {@code byte2bool} implements that conversion. + * + * @param b the byte to be converted to boolean + * @return the result of the conversion + */ @ForceInline private boolean byte2bool(byte b) { - return b > 0; - } - + return b != 0; + } + + /** + * Convert a boolean value to a byte. The return value is strongly + * normalized to the value-set 0..1 (i.e., the value is truncated + * to the least-significant bit). See {@link #byte2bool(byte)} for + * more details on conversion conventions. + * + * @param b the boolean to be converted to byte (and then normalized) + * @return the result of the conversion + */ @ForceInline private byte bool2byte(boolean b) { return b ? (byte)1 : (byte)0; diff -r 805dd7bef81f -r 9fb8c8e7528e jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java --- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java Thu Sep 15 21:08:59 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java Fri Sep 16 10:57:21 2016 -0700 @@ -153,27 +153,24 @@ boolean addAllDefaultModules = false; boolean addAllSystemModules = false; boolean addAllApplicationModules = false; - String propValue = getAndRemoveProperty("jdk.module.addmods"); - if (propValue != null) { - for (String mod: propValue.split(",")) { - switch (mod) { - case ALL_DEFAULT: - addAllDefaultModules = true; - break; - case ALL_SYSTEM: - addAllSystemModules = true; - break; - case ALL_MODULE_PATH: - addAllApplicationModules = true; - break; - default : - roots.add(mod); - } + for (String mod: getExtraAddModules()) { + switch (mod) { + case ALL_DEFAULT: + addAllDefaultModules = true; + break; + case ALL_SYSTEM: + addAllSystemModules = true; + break; + case ALL_MODULE_PATH: + addAllApplicationModules = true; + break; + default : + roots.add(mod); } } // --limit-modules - propValue = getAndRemoveProperty("jdk.module.limitmods"); + String propValue = getAndRemoveProperty("jdk.module.limitmods"); if (propValue != null) { Set mods = new HashSet<>(); for (String mod: propValue.split(",")) { @@ -392,6 +389,32 @@ } } + /** + * Returns the set of module names specified via --add-modules options + * on the command line + */ + private static Set getExtraAddModules() { + String prefix = "jdk.module.addmods."; + int index = 0; + + // the system property is removed after decoding + String value = getAndRemoveProperty(prefix + index); + if (value == null) { + return Collections.emptySet(); + } + + Set modules = new HashSet<>(); + while (value != null) { + for (String s : value.split(",")) { + if (s.length() > 0) modules.add(s); + } + + index++; + value = getAndRemoveProperty(prefix + index); + } + + return modules; + } /** * Process the --add-reads options to add any additional read edges that @@ -514,7 +537,7 @@ // value is (,)* if (map.containsKey(key)) - fail(key + " specified more than once"); + fail(key + " specified more than once"); Set values = new HashSet<>(); map.put(key, values); diff -r 805dd7bef81f -r 9fb8c8e7528e jdk/src/java.base/share/native/include/jvm.h --- a/jdk/src/java.base/share/native/include/jvm.h Thu Sep 15 21:08:59 2016 +0000 +++ b/jdk/src/java.base/share/native/include/jvm.h Fri Sep 16 10:57:21 2016 -0700 @@ -179,6 +179,7 @@ */ enum { JVM_STACKWALK_FILL_CLASS_REFS_ONLY = 0x2, + JVM_STACKWALK_GET_CALLER_CLASS = 0x04, JVM_STACKWALK_SHOW_HIDDEN_FRAMES = 0x20, JVM_STACKWALK_FILL_LIVE_STACK_FRAMES = 0x100 }; diff -r 805dd7bef81f -r 9fb8c8e7528e jdk/test/java/lang/StackWalker/CallerSensitiveMethod/Main.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/StackWalker/CallerSensitiveMethod/Main.java Fri Sep 16 10:57:21 2016 -0700 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8157464 + * @summary Basic test for StackWalker.getCallerClass() + * @library src + * @build java.base/java.util.CSM csm/* + * @run main/othervm csm/jdk.test.CallerSensitiveTest + * @run main/othervm csm/jdk.test.CallerSensitiveTest sm + */ +public class Main { +} + diff -r 805dd7bef81f -r 9fb8c8e7528e jdk/test/java/lang/StackWalker/CallerSensitiveMethod/csm/jdk/test/CallerSensitiveTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/StackWalker/CallerSensitiveMethod/csm/jdk/test/CallerSensitiveTest.java Fri Sep 16 10:57:21 2016 -0700 @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.test; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodHandles.Lookup; +import java.lang.invoke.MethodType; +import java.lang.reflect.Method; +import java.security.Permission; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.security.Policy; +import java.security.ProtectionDomain; +import java.util.CSM.Result; +import java.util.function.Supplier; + +/** + * This test invokes StackWalker::getCallerClass via static reference, + * reflection, MethodHandle, lambda. Also verify that + * StackWalker::getCallerClass can't be called from @CallerSensitive method. + */ +public class CallerSensitiveTest { + private static final String NON_CSM_CALLER_METHOD = "getCallerClass"; + private static final String CSM_CALLER_METHOD = "caller"; + + public static void main(String... args) throws Throwable { + boolean sm = false; + if (args.length > 0 && args[0].equals("sm")) { + sm = true; + PermissionCollection perms = new Permissions(); + perms.add(new StackFramePermission("retainClassReference")); + Policy.setPolicy(new Policy() { + @Override + public boolean implies(ProtectionDomain domain, Permission p) { + return perms.implies(p); + } + }); + System.setSecurityManager(new SecurityManager()); + } + + System.err.format("Test %s security manager.%n", + sm ? "with" : "without"); + + CallerSensitiveTest cstest = new CallerSensitiveTest(); + // test static call to java.util.CSM::caller and CSM::getCallerClass + cstest.staticMethodCall(); + // test java.lang.reflect.Method call + cstest.reflectMethodCall(); + // test java.lang.invoke.MethodHandle + cstest.invokeMethodHandle(Lookup1.lookup); + cstest.invokeMethodHandle(Lookup2.lookup); + // test method ref + cstest.lambda(); + + LambdaTest.lambda(); + + if (failed > 0) { + throw new RuntimeException(failed + " test cases failed."); + } + } + + void staticMethodCall() { + java.util.CSM.caller(); + + Result result = java.util.CSM.getCallerClass(); + checkNonCSMCaller(CallerSensitiveTest.class, result); + } + + void reflectMethodCall() throws Throwable { + Method method1 = java.util.CSM.class.getMethod(CSM_CALLER_METHOD); + method1.invoke(null); + + Method method2 = java.util.CSM.class.getMethod(NON_CSM_CALLER_METHOD); + Result result = (Result) method2.invoke(null); + checkNonCSMCaller(CallerSensitiveTest.class, result); + } + + void invokeMethodHandle(Lookup lookup) throws Throwable { + MethodHandle mh1 = lookup.findStatic(java.util.CSM.class, CSM_CALLER_METHOD, + MethodType.methodType(Class.class)); + Class c = (Class)mh1.invokeExact(); + + MethodHandle mh2 = lookup.findStatic(java.util.CSM.class, NON_CSM_CALLER_METHOD, + MethodType.methodType(Result.class)); + Result result = (Result)mh2.invokeExact(); + checkNonCSMCaller(CallerSensitiveTest.class, result); + } + + void lambda() { + Result result = LambdaTest.getCallerClass.get(); + checkNonCSMCaller(CallerSensitiveTest.class, result); + + LambdaTest.caller.get(); + } + + static int failed = 0; + + static void checkNonCSMCaller(Class expected, Result result) { + if (result.callers.size() != 1) { + throw new RuntimeException("Expected result.callers contain one element"); + } + if (expected != result.callers.get(0)) { + System.err.format("ERROR: Expected %s but got %s%n", expected, + result.callers); + result.frames.stream() + .forEach(f -> System.err.println(" " + f)); + failed++; + } + } + + static class Lookup1 { + static Lookup lookup = MethodHandles.lookup(); + } + + static class Lookup2 { + static Lookup lookup = MethodHandles.lookup(); + } + + static class LambdaTest { + static Supplier> caller = java.util.CSM::caller; + static Supplier getCallerClass = java.util.CSM::getCallerClass; + + static void caller() { + caller.get(); + } + static Result getCallerClass() { + return getCallerClass.get(); + } + + static void lambda() { + Result result = LambdaTest.getCallerClass(); + checkNonCSMCaller(LambdaTest.class, result); + + LambdaTest.caller(); + } + } +} diff -r 805dd7bef81f -r 9fb8c8e7528e jdk/test/java/lang/StackWalker/CallerSensitiveMethod/csm/module-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/StackWalker/CallerSensitiveMethod/csm/module-info.java Fri Sep 16 10:57:21 2016 -0700 @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +module csm { + exports jdk.test; +} diff -r 805dd7bef81f -r 9fb8c8e7528e jdk/test/java/lang/StackWalker/CallerSensitiveMethod/src/java.base/java/util/CSM.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/StackWalker/CallerSensitiveMethod/src/java.base/java/util/CSM.java Fri Sep 16 10:57:21 2016 -0700 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.util; + +import static java.lang.StackWalker.Option.*; +import java.lang.StackWalker.StackFrame; +import java.util.stream.Collectors; + +import jdk.internal.reflect.CallerSensitive; +import jdk.internal.reflect.Reflection; + +public class CSM { + private static StackWalker walker = + StackWalker.getInstance(EnumSet.of(RETAIN_CLASS_REFERENCE, + SHOW_HIDDEN_FRAMES, + SHOW_REFLECT_FRAMES)); + + public static class Result { + public final List> callers; + public final List frames; + Result(List> callers, + List frames) { + this.callers = callers; + this.frames = frames; + } + } + + /** + * Returns the caller of this caller-sensitive method returned by + * by Reflection::getCallerClass. + * + * StackWalker::getCallerClass is expected to throw UOE + */ + @CallerSensitive + public static Class caller() { + Class c1 = Reflection.getCallerClass(); + + try { + Class c2 = walker.getCallerClass(); + throw new RuntimeException("Exception not thrown by StackWalker::getCallerClass"); + } catch (UnsupportedOperationException e) {} + return c1; + } + + /** + * Returns the caller of this non-caller-sensitive method. + */ + public static Result getCallerClass() { + Class caller = walker.getCallerClass(); + return new Result(List.of(caller), dump()); + } + + static List dump() { + return walker.walk(s -> s.collect(Collectors.toList())); + } +} diff -r 805dd7bef81f -r 9fb8c8e7528e jdk/test/java/lang/instrument/SimpleAgent.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/instrument/SimpleAgent.java Fri Sep 16 10:57:21 2016 -0700 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.instrument.Instrumentation; + +class SimpleAgent { + + public static void premain(String args, Instrumentation inst) { + System.out.println("in premain"); + } + +} diff -r 805dd7bef81f -r 9fb8c8e7528e jdk/test/java/lang/instrument/TestAgentWithLimitMods.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/instrument/TestAgentWithLimitMods.java Fri Sep 16 10:57:21 2016 -0700 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * + * @test + * @summary Tests that the -javaagent option adds the java.instrument into + * the module graph + * @modules java.instrument + * @run shell MakeJAR3.sh SimpleAgent + * @run main/othervm -javaagent:SimpleAgent.jar -limitmods java.base TestAgentWithLimitMods + * + */ +public class TestAgentWithLimitMods { + + public static void main(String[] args) { + System.out.println("Test passed"); + } + +} diff -r 805dd7bef81f -r 9fb8c8e7528e jdk/test/jdk/internal/misc/Unsafe/TestBadHostClass.java --- a/jdk/test/jdk/internal/misc/Unsafe/TestBadHostClass.java Thu Sep 15 21:08:59 2016 +0000 +++ b/jdk/test/jdk/internal/misc/Unsafe/TestBadHostClass.java Fri Sep 16 10:57:21 2016 -0700 @@ -25,7 +25,6 @@ * @test * @bug 8058575 * @summary Test that bad host classes cause exceptions to get thrown. - * @library /test/lib * @modules java.base/jdk.internal.misc * java.base/jdk.internal.org.objectweb.asm * @run main TestBadHostClass @@ -35,7 +34,6 @@ import java.lang.*; import java.lang.reflect.Field; import jdk.internal.misc.Unsafe; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.org.objectweb.asm.ClassWriter; import static jdk.internal.org.objectweb.asm.Opcodes.*; diff -r 805dd7bef81f -r 9fb8c8e7528e jdk/test/tools/launcher/TooSmallStackSize.java --- a/jdk/test/tools/launcher/TooSmallStackSize.java Thu Sep 15 21:08:59 2016 +0000 +++ b/jdk/test/tools/launcher/TooSmallStackSize.java Fri Sep 16 10:57:21 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,11 @@ * stack size for the platform (as provided by the JVM error message when a very * small stack is used), and then verify that the JVM can be launched with that stack * size without a crash or any error messages. + * + * Note: The '-Xss' and '-XX:ThreadStackSize=' options + * both control Java thread stack size. This repo's version of the test + * exercises the '-Xss' option. The hotspot repo's version of the test + * exercises the '-XX:ThreadStackSize' VM option. */ public class TooSmallStackSize extends TestHelper { @@ -59,7 +64,7 @@ static String getMinStackAllowed(TestResult tr) { /* * The JVM output will contain in one of the lines: - * "The stack size specified is too small, Specify at least 100k" + * "The Java thread stack size specified is too small. Specify at least 100k" * Although the actual size will vary. We need to extract this size * string from the output and return it. */ @@ -73,6 +78,9 @@ } } + System.out.println("Expect='" + matchStr + "'"); + System.out.println("Actual:"); + printTestOutput(tr); System.out.println("FAILED: Could not get the stack size from the output"); throw new RuntimeException("test fails"); } @@ -96,11 +104,15 @@ System.out.println("PASSED: got no error message with stack size of " + stackSize); min_stack_allowed = stackSize; } else { - if (tr.contains("The stack size specified is too small")) { + String matchStr = "The Java thread stack size specified is too small"; + if (tr.contains(matchStr)) { System.out.println("PASSED: got expected error message with stack size of " + stackSize); min_stack_allowed = getMinStackAllowed(tr); } else { // Likely a crash + System.out.println("Expect='" + matchStr + "'"); + System.out.println("Actual:"); + printTestOutput(tr); System.out.println("FAILED: Did not get expected error message with stack size of " + stackSize); throw new RuntimeException("test fails"); } @@ -123,6 +135,8 @@ System.out.println("PASSED: VM launched with minimum allowed stack size of " + stackSize); } else { // Likely a crash + System.out.println("Test output:"); + printTestOutput(tr); System.out.println("FAILED: VM failed to launch with minimum allowed stack size of " + stackSize); throw new RuntimeException("test fails"); } diff -r 805dd7bef81f -r 9fb8c8e7528e jdk/test/tools/launcher/modules/addmods/AddModsTest.java --- a/jdk/test/tools/launcher/modules/addmods/AddModsTest.java Thu Sep 15 21:08:59 2016 +0000 +++ b/jdk/test/tools/launcher/modules/addmods/AddModsTest.java Fri Sep 16 10:57:21 2016 -0700 @@ -31,6 +31,7 @@ * @summary Basic test for java --add-modules */ +import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; @@ -224,6 +225,27 @@ /** + * Tests {@code --add-modules} be specified more than once. + */ + public void testWithMultipleAddModules() throws Exception { + + String modulepath = MODS1_DIR.toString() + File.pathSeparator + + MODS2_DIR.toString(); + int exitValue + = executeTestJava("--module-path", modulepath, + "--add-modules", LOGGER_MODULE, + "--add-modules", TEST_MODULE, + "-m", TEST_MID, + "logger.Logger") + .outputTo(System.out) + .errorTo(System.out) + .getExitValue(); + + assertTrue(exitValue == 0); + } + + + /** * Attempt to run with a bad module name specified to --add-modules */ public void testRunWithBadAddMods() throws Exception {