From 23264135ec1b9fbbb11017bfdd6fa1189e8019e7 Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Mon, 27 Jun 2016 20:22:04 -0700 Subject: [PATCH] 8159596: Add java --dry-run Reviewed-by: alanb, ksrini --- .../launcher/resources/launcher.properties | 3 + jdk/src/java.base/share/native/libjli/java.c | 21 +- .../launcher/modules/dryrun/DryRunTest.java | 199 ++++++++++++++++++ .../modules/dryrun/src/m/module-info.java | 26 +++ .../launcher/modules/dryrun/src/m/p/Lib.java | 30 +++ .../dryrun/src/test/jdk/test/Main.java | 30 +++ .../modules/dryrun/src/test/module-info.java | 26 +++ 7 files changed, 328 insertions(+), 7 deletions(-) create mode 100644 jdk/test/tools/launcher/modules/dryrun/DryRunTest.java create mode 100644 jdk/test/tools/launcher/modules/dryrun/src/m/module-info.java create mode 100644 jdk/test/tools/launcher/modules/dryrun/src/m/p/Lib.java create mode 100644 jdk/test/tools/launcher/modules/dryrun/src/test/jdk/test/Main.java create mode 100644 jdk/test/tools/launcher/modules/dryrun/src/test/module-info.java diff --git a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties index 32aa8ec65b3..83b328d7de8 100644 --- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties +++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties @@ -60,6 +60,9 @@ java.launcher.opt.footer =\ -cp [,...]]\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=\n\ \ set a system property\n\ \ -verbose:[class|gc|jni]\n\ diff --git a/jdk/src/java.base/share/native/libjli/java.c b/jdk/src/java.base/share/native/libjli/java.c index c771d993bfe..ffd60727128 100644 --- a/jdk/src/java.base/share/native/libjli/java.c +++ b/jdk/src/java.base/share/native/libjli/java.c @@ -68,6 +68,7 @@ static jboolean printVersion = JNI_FALSE; /* print and exit */ 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 @@ JavaMain(void * _args) 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 @@ ParseArguments(int *pargc, char ***pargv, 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; diff --git a/jdk/test/tools/launcher/modules/dryrun/DryRunTest.java b/jdk/test/tools/launcher/modules/dryrun/DryRunTest.java new file mode 100644 index 00000000000..ca87bf88679 --- /dev/null +++ b/jdk/test/tools/launcher/modules/dryrun/DryRunTest.java @@ -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; + } +} diff --git a/jdk/test/tools/launcher/modules/dryrun/src/m/module-info.java b/jdk/test/tools/launcher/modules/dryrun/src/m/module-info.java new file mode 100644 index 00000000000..6ebed006a4b --- /dev/null +++ b/jdk/test/tools/launcher/modules/dryrun/src/m/module-info.java @@ -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; +} diff --git a/jdk/test/tools/launcher/modules/dryrun/src/m/p/Lib.java b/jdk/test/tools/launcher/modules/dryrun/src/m/p/Lib.java new file mode 100644 index 00000000000..1c8159b7b13 --- /dev/null +++ b/jdk/test/tools/launcher/modules/dryrun/src/m/p/Lib.java @@ -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"); + } +} diff --git a/jdk/test/tools/launcher/modules/dryrun/src/test/jdk/test/Main.java b/jdk/test/tools/launcher/modules/dryrun/src/test/jdk/test/Main.java new file mode 100644 index 00000000000..547e8eb53b0 --- /dev/null +++ b/jdk/test/tools/launcher/modules/dryrun/src/test/jdk/test/Main.java @@ -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(); + } +} diff --git a/jdk/test/tools/launcher/modules/dryrun/src/test/module-info.java b/jdk/test/tools/launcher/modules/dryrun/src/test/module-info.java new file mode 100644 index 00000000000..bc5cd5d4e14 --- /dev/null +++ b/jdk/test/tools/launcher/modules/dryrun/src/test/module-info.java @@ -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; +}