--- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties Tue Jun 28 00:39:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties Mon Jun 27 20:22:04 2016 -0700
@@ -60,6 +60,9 @@
\ limit the universe of observable modules\n\
\ -listmods[:<modulename>[,<modulename>...]]\n\
\ list the observable modules and exit\n\
+\ --dry-run create VM but do not execute main method.\n\
+\ This --dry-run option may be useful for validating the\n\
+\ command-line options such as the module system configuration.\n\
\ -D<name>=<value>\n\
\ set a system property\n\
\ -verbose:[class|gc|jni]\n\
--- a/jdk/src/java.base/share/native/libjli/java.c Tue Jun 28 00:39:26 2016 +0200
+++ b/jdk/src/java.base/share/native/libjli/java.c Mon Jun 27 20:22:04 2016 -0700
@@ -68,6 +68,7 @@
static jboolean showVersion = JNI_FALSE; /* print but continue */
static jboolean printUsage = JNI_FALSE; /* print and exit*/
static jboolean printXUsage = JNI_FALSE; /* print and exit*/
+static jboolean dryRun = JNI_FALSE; /* initialize VM and exit */
static char *showSettings = NULL; /* print but continue */
static char *listModules = NULL;
@@ -489,14 +490,18 @@
mainArgs = CreateApplicationArgs(env, argv, argc);
CHECK_EXCEPTION_NULL_LEAVE(mainArgs);
- /* Invoke main method. */
- (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
+ if (dryRun) {
+ ret = 0;
+ } else {
+ /* Invoke main method. */
+ (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
- /*
- * The launcher's exit code (in the absence of calls to
- * System.exit) will be non-zero if main threw an exception.
- */
- ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1;
+ /*
+ * The launcher's exit code (in the absence of calls to
+ * System.exit) will be non-zero if main threw an exception.
+ */
+ ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1;
+ }
LEAVE();
}
@@ -1203,6 +1208,8 @@
return JNI_TRUE;
} else if (JLI_StrCmp(arg, "-showversion") == 0) {
showVersion = JNI_TRUE;
+ } else if (JLI_StrCmp(arg, "--dry-run") == 0) {
+ dryRun = JNI_TRUE;
} else if (JLI_StrCmp(arg, "-X") == 0) {
printXUsage = JNI_TRUE;
return JNI_TRUE;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/modules/dryrun/DryRunTest.java Mon Jun 27 20:22:04 2016 -0700
@@ -0,0 +1,199 @@
+/*
+ * 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 8159596
+ * @library /lib/testlibrary
+ * @modules jdk.compiler
+ * jdk.jartool/sun.tools.jar
+ * @build DryRunTest CompilerUtils jdk.testlibrary.ProcessTools
+ * @run testng DryRunTest
+ * @summary Test java --dry-run
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import jdk.testlibrary.ProcessTools;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+
+@Test
+public class DryRunTest {
+
+ private static final String TEST_SRC = System.getProperty("test.src");
+
+ private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
+ private static final Path MODS_DIR = Paths.get("mods");
+ private static final Path LIBS_DIR = Paths.get("libs");
+
+ // the module name of the test module
+ private static final String TEST_MODULE = "test";
+ private static final String M_MODULE = "m";
+
+ // the module main class
+ private static final String MAIN_CLASS = "jdk.test.Main";
+
+
+ @BeforeTest
+ public void compileTestModule() throws Exception {
+
+ // javac -d mods/$TESTMODULE src/$TESTMODULE/**
+ assertTrue(CompilerUtils.compile(SRC_DIR.resolve(M_MODULE),
+ MODS_DIR,
+ "-modulesourcepath", SRC_DIR.toString()));
+
+ assertTrue(CompilerUtils.compile(SRC_DIR.resolve(TEST_MODULE),
+ MODS_DIR,
+ "-modulesourcepath", SRC_DIR.toString()));
+
+ Files.createDirectories(LIBS_DIR);
+
+ // create JAR files with no module-info.class
+ assertTrue(jar(M_MODULE, "p/Lib.class"));
+ assertTrue(jar(TEST_MODULE, "jdk/test/Main.class"));
+ }
+
+ /**
+ * Execute "java" with the given arguments, returning the exit code.
+ */
+ private int exec(String... args) throws Exception {
+ return ProcessTools.executeTestJava(args)
+ .outputTo(System.out)
+ .errorTo(System.out)
+ .getExitValue();
+ }
+
+
+ /**
+ * Launch module main
+ */
+ public void testModule() throws Exception {
+ String dir = MODS_DIR.toString();
+ String mid = TEST_MODULE + "/" + MAIN_CLASS;
+
+ // java -modulepath mods -module $TESTMODULE/$MAINCLASS
+ // no resolution failure
+ int exitValue = exec("--dry-run", "-modulepath", dir, "-m", mid);
+ assertTrue(exitValue == 0);
+ }
+
+ /**
+ * Test non-existence module in -addmods
+ */
+ public void testNonExistAddModules() throws Exception {
+ String dir = MODS_DIR.toString();
+ String mid = TEST_MODULE + "/" + MAIN_CLASS;
+
+ int exitValue = exec("--dry-run", "-modulepath", dir,
+ "-addmods", "non.existence",
+ "-m", mid);
+ assertTrue(exitValue != 0);
+ }
+
+ /**
+ * Launch main class from class path
+ */
+ public void testClassPath() throws Exception {
+ Path testJar = LIBS_DIR.resolve(TEST_MODULE + ".jar");
+ String libs = testJar.toString() + File.pathSeparator +
+ LIBS_DIR.resolve(M_MODULE + ".jar").toString();
+
+ // test pass with m.jar:test.jar
+ int exitValue = exec("-classpath", libs, MAIN_CLASS);
+ assertTrue(exitValue == 0);
+
+ // m.jar is not on classpath and fails with p.Lib not found
+ exitValue = exec("-classpath", testJar.toString(), MAIN_CLASS);
+ assertTrue(exitValue != 0);
+
+ // dry pass passes since main is not executed
+ exitValue = exec("--dry-run", "-classpath", testJar.toString(), MAIN_CLASS);
+ assertTrue(exitValue == 0);
+ }
+
+ /**
+ * Test automatic modules
+ */
+ public void testAutomaticModule() throws Exception {
+ String libs = LIBS_DIR.resolve(M_MODULE + ".jar").toString() +
+ File.pathSeparator +
+ LIBS_DIR.resolve(TEST_MODULE + ".jar").toString();
+ String mid = TEST_MODULE + "/" + MAIN_CLASS;
+
+ // test main method with and without -addmods mm
+ int exitValue = exec("-modulepath", LIBS_DIR.toString(),
+ "-m", mid);
+ assertTrue(exitValue != 0);
+
+ exitValue = exec("-modulepath", LIBS_DIR.toString(),
+ "-addmods", M_MODULE,
+ "-m", mid);
+ assertTrue(exitValue == 0);
+
+ // test dry run with and without -addmods m
+ // no resolution failure
+ exitValue = exec("--dry-run", "-modulepath", LIBS_DIR.toString(),
+ "-m", mid);
+ assertTrue(exitValue == 0);
+
+ exitValue = exec("--dry-run", "-modulepath", LIBS_DIR.toString(),
+ "-addmods", M_MODULE,
+ "-m", mid);
+ assertTrue(exitValue == 0);
+ }
+
+ /**
+ * module m not found
+ */
+ public void testMissingModule() throws Exception {
+ String subdir = MODS_DIR.resolve(TEST_MODULE).toString();
+ String mid = TEST_MODULE + "/" + MAIN_CLASS;
+
+ // resolution failure
+ int exitValue = exec("--dry-run", "-modulepath", subdir, "-m", mid);
+ assertTrue(exitValue != 0);
+ }
+
+ private static boolean jar(String name, String entries) throws IOException {
+ Path jar = LIBS_DIR.resolve(name + ".jar");
+
+ // jar --create ...
+ String classes = MODS_DIR.resolve(name).toString();
+ String[] args = {
+ "--create",
+ "--file=" + jar,
+ "-C", classes, entries
+ };
+ boolean success
+ = new sun.tools.jar.Main(System.out, System.out, "jar").run(args);
+ return success;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/modules/dryrun/src/m/module-info.java Mon Jun 27 20:22:04 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 m {
+ exports p;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/modules/dryrun/src/m/p/Lib.java Mon Jun 27 20:22:04 2016 -0700
@@ -0,0 +1,30 @@
+/*
+ * 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 p;
+
+public class Lib {
+ public static void sayHi() {
+ System.out.println("Hello world");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/modules/dryrun/src/test/jdk/test/Main.java Mon Jun 27 20:22:04 2016 -0700
@@ -0,0 +1,30 @@
+/*
+ * 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;
+
+public class Main {
+ public static void main(String[] args) {
+ p.Lib.sayHi();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/modules/dryrun/src/test/module-info.java Mon Jun 27 20:22:04 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 test {
+ requires m;
+}