langtools/test/tools/javac/modules/InheritRuntimeEnvironmentTest.java
changeset 40308 274367a99f98
child 40513 39b67170b045
equal deleted inserted replaced
40306:1a0fcaf3f2ed 40308:274367a99f98
       
     1 /*
       
     2  * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 /**
       
    25  * @test
       
    26  * @bug 8156998
       
    27  * @summary Test --inherit-runtime-environment
       
    28  * @library /tools/lib
       
    29  * @modules
       
    30  *      jdk.compiler/com.sun.tools.javac.api
       
    31  *      jdk.compiler/com.sun.tools.javac.main
       
    32  * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask toolbox.JavaTask ModuleTestBase
       
    33  * @run main InheritRuntimeEnvironmentTest
       
    34  */
       
    35 
       
    36 import java.io.IOException;
       
    37 import java.nio.file.Files;
       
    38 import java.nio.file.Path;
       
    39 import java.util.Arrays;
       
    40 import java.util.Collections;
       
    41 import java.util.List;
       
    42 import java.util.stream.Collectors;
       
    43 
       
    44 import toolbox.ModuleBuilder;
       
    45 import toolbox.JavaTask;
       
    46 import toolbox.JavacTask;
       
    47 import toolbox.Task;
       
    48 
       
    49 /**
       
    50  * Tests that javac picks up runtime options with --inherit-runtime-environment.
       
    51  * For each option, javac is first run using the option directly, as a control.
       
    52  * javac is then run again, with the same option(s) being passed to the runtime,
       
    53  * and --inherit-runtime-environment being used by javac.
       
    54  * @author jjg
       
    55  */
       
    56 public class InheritRuntimeEnvironmentTest extends ModuleTestBase {
       
    57     public static void main(String... args) throws Exception {
       
    58         InheritRuntimeEnvironmentTest t = new InheritRuntimeEnvironmentTest();
       
    59         t.runTests();
       
    60     }
       
    61 
       
    62     /**
       
    63      * Tests that code being compiled can access JDK-internal API using -add-exports.
       
    64      * @param base
       
    65      * @throws Exception
       
    66      */
       
    67     @Test
       
    68     public void testAddExports(Path base) throws Exception {
       
    69         Path src = base.resolve("src");
       
    70         tb.writeJavaFiles(src,
       
    71                 "class C { com.sun.tools.javac.main.Main main; }");
       
    72 
       
    73         new TestCase(base)
       
    74                 .testOpts("--add-exports", "jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED")
       
    75                 .files(findJavaFiles(src))
       
    76                 .run();
       
    77     }
       
    78 
       
    79     /**
       
    80      * Tests that code in the unnamed module can access a module on the module path using --add-modules.
       
    81      */
       
    82     @Test
       
    83     public void testAddModules(Path base) throws Exception {
       
    84         Path modules = base.resolve("modules");
       
    85         new ModuleBuilder(tb, "m1")
       
    86                 .exports("pkg1")
       
    87                 .classes("package pkg1; public class C1 { }")
       
    88                 .build(modules);
       
    89 
       
    90         Path src = base.resolve("src");
       
    91         tb.writeJavaFiles(src,
       
    92                 "class C { pkg1.C1 c1; }");
       
    93 
       
    94         new TestCase(base)
       
    95                 .testOpts("--module-path", modules.toString(), "--add-modules", "m1")
       
    96                 .files(findJavaFiles(src))
       
    97                 .run();
       
    98     }
       
    99 
       
   100     /**
       
   101      * Tests that a module on the module path is not visible when --limit-modules is used to
       
   102      * restrict the set of observable modules.
       
   103      */
       
   104     @Test
       
   105     public void testLimitModules(Path base) throws Exception {
       
   106         Path modules = base.resolve("modules");
       
   107         new ModuleBuilder(tb, "m1")
       
   108                 .exports("pkg1")
       
   109                 .classes("package pkg1; public class C1 { }")
       
   110                 .build(modules);
       
   111 
       
   112         Path src = base.resolve("src");
       
   113         new ModuleBuilder(tb, "m2")
       
   114                 .requires("m1")
       
   115                 .classes("package pkg2; public class C2 { pkg1.C1 c1; }")
       
   116                 .write(src);
       
   117 
       
   118         // This is the control, to verify that by default, the module being compiled will
       
   119         // be able to read modules on the module path
       
   120         new TestCase(base)
       
   121                 .testOpts("--module-path", modules.toString())
       
   122                 .otherOpts("--module-source-path", src.toString())
       
   123                 .files(findJavaFiles(src))
       
   124                 .run();
       
   125 
       
   126         // This is the test, to verify that the module being compiled will not be able to read
       
   127         // modules on the module path when a --limit-modules is used
       
   128         new TestCase(base)
       
   129                 .testOpts("--module-path", modules.toString(), "--limit-modules", "jdk.compiler")
       
   130                 .otherOpts("-XDrawDiagnostics",
       
   131                         "--module-source-path", src.toString())
       
   132                 .files(findJavaFiles(src))
       
   133                 .expect(Task.Expect.FAIL, "compiler.err.module.not.found")
       
   134                 .run();
       
   135     }
       
   136 
       
   137     /**
       
   138      * Tests that a module being compiled can see another module on the module path
       
   139      * using --module-path.
       
   140      */
       
   141     @Test
       
   142     public void testModulePath(Path base) throws Exception {
       
   143         Path modules = base.resolve("modules");
       
   144         new ModuleBuilder(tb, "m1")
       
   145                 .exports("pkg1")
       
   146                 .classes("package pkg1; public class C1 { }")
       
   147                 .build(modules);
       
   148 
       
   149         Path src = base.resolve("src");
       
   150         new ModuleBuilder(tb, "m2")
       
   151                 .requires("m1")
       
   152                 .classes("package pkg2; public class C2 { pkg1.C1 c1; }")
       
   153                 .write(src);
       
   154 
       
   155         new TestCase(base)
       
   156                 .testOpts("--module-path", modules.toString())
       
   157                 .otherOpts("--module-source-path", src.toString())
       
   158                 .files(findJavaFiles(src))
       
   159                 .run();
       
   160     }
       
   161 
       
   162     /**
       
   163      * Tests that a module being compiled can see classes patches into an existing module
       
   164      * with --patch-module
       
   165      */
       
   166     @Test
       
   167     public void testPatchModule(Path base) throws Exception {
       
   168         Path patchSrc = base.resolve("patchSrc");
       
   169         tb.writeJavaFiles(patchSrc,
       
   170                 "package java.util; public class Xyzzy { }");
       
   171         Path patch = base.resolve("patch");
       
   172         Files.createDirectories(patch);
       
   173 
       
   174         new JavacTask(tb)
       
   175                 .options("-Xmodule:java.base")
       
   176                 .outdir(patch)
       
   177                 .sourcepath(patchSrc)
       
   178                 .files(findJavaFiles(patchSrc))
       
   179                 .run()
       
   180                 .writeAll();
       
   181 
       
   182         Path src = base.resolve("src");
       
   183         tb.writeJavaFiles(src,
       
   184                 "public class C { java.util.Xyzzy x; }");
       
   185 
       
   186         new TestCase(base)
       
   187                 .testOpts("--patch-module", "java.base=" + patch)
       
   188                 .files(findJavaFiles(src))
       
   189                 .run();
       
   190     }
       
   191 
       
   192     /**
       
   193      * Tests that options in @files are also effective.
       
   194      * The test is similar to testModulePath, except that the test options are provided in an @-file.
       
   195      */
       
   196     @Test
       
   197     public void testAtFile(Path base) throws Exception {
       
   198         Path modules = base.resolve("modules");
       
   199         new ModuleBuilder(tb, "m1")
       
   200                 .exports("pkg1")
       
   201                 .classes("package pkg1; public class C1 { }")
       
   202                 .build(modules);
       
   203 
       
   204         Path src = base.resolve("src");
       
   205         new ModuleBuilder(tb, "m2")
       
   206                 .requires("m1")
       
   207                 .classes("package pkg2; public class C2 { pkg1.C1 c1; }")
       
   208                 .write(src);
       
   209 
       
   210         Path atFile = base.resolve("atFile");
       
   211         tb.writeFile(atFile, "--module-path " + modules);
       
   212 
       
   213         new TestCase(base)
       
   214                 .testOpts("@" + atFile)
       
   215                 .otherOpts("--module-source-path", src.toString())
       
   216                 .files(findJavaFiles(src))
       
   217                 .run();
       
   218     }
       
   219 
       
   220     /**
       
   221      * Tests that --inherit-runtime-environment works in conjunction with
       
   222      * environment variables.
       
   223      * This is a variant of testAddExports.
       
   224      * The use of environment variables is sufficiently custom that it is
       
   225      * not easy to do this directly with a simple TestCase.
       
   226      */
       
   227     @Test
       
   228     public void testEnvVars(Path base) throws Exception {
       
   229         Path src = base.resolve("src");
       
   230         tb.writeJavaFiles(src,
       
   231                 "class C { com.sun.tools.javac.main.Main main; }");
       
   232         List<String> testOpts =
       
   233                 Arrays.asList("--add-exports", "jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED");
       
   234         List<Path> files = Arrays.asList(findJavaFiles(src));
       
   235 
       
   236         String envName = "_JAVAC_OPTIONS";
       
   237         String envValue = String.join(" ", testOpts);
       
   238 
       
   239         out.println("  javac:");
       
   240         Path javacOutDir = base.resolve("out-javac");
       
   241         Files.createDirectories(javacOutDir);
       
   242 
       
   243         out.println("    env: " + envName + "=" + envValue);
       
   244         out.println("    outdir: " + javacOutDir);
       
   245         out.println("    files: " + files);
       
   246 
       
   247         new JavacTask(tb, Task.Mode.EXEC)
       
   248                 .envVar(envName, envValue)
       
   249                 .outdir(javacOutDir)
       
   250                 .files(files)
       
   251                 .run()
       
   252                 .writeAll()
       
   253                 .getOutput(Task.OutputKind.DIRECT);
       
   254 
       
   255         out.println("  java:");
       
   256         Path javaOutDir = base.resolve("out-java");
       
   257         Files.createDirectories(javaOutDir);
       
   258 
       
   259         Path atFile = base.resolve("atFile");
       
   260         tb.writeFile(atFile, String.join(" ", testOpts));
       
   261 
       
   262         List<String> vmOpts = Arrays.asList(
       
   263                 "@" + atFile,
       
   264                 "--module", "jdk.compiler/com.sun.tools.javac.Main"
       
   265         );
       
   266 
       
   267         List<String> classArgs = join(
       
   268                 Arrays.asList("-d", javaOutDir.toString()),
       
   269                 files.stream()
       
   270                         .map(p -> p.toString())
       
   271                         .collect(Collectors.toList())
       
   272         );
       
   273 
       
   274         envValue = "--inherit-runtime-environment";
       
   275 
       
   276         out.println("    env: " + envName + "=" + envValue);
       
   277         out.println("    vmOpts: " + vmOpts);
       
   278         out.println("    classArgs: " + classArgs);
       
   279 
       
   280         new JavaTask(tb)
       
   281                 .envVar(envName, envValue)
       
   282                 .vmOptions(vmOpts)
       
   283                 .classArgs(classArgs)
       
   284                 .run()
       
   285                 .writeAll()
       
   286                 .getOutput(Task.OutputKind.STDERR);
       
   287     }
       
   288 
       
   289     /**
       
   290      * Runs javac with given test options,  first directly, and then again, specifying the
       
   291      * options to the runtime, and using --inherit-runtime-environment.
       
   292      */
       
   293     class TestCase {
       
   294         final Path base;
       
   295         List<String> testOpts = Collections.emptyList();
       
   296         List<String> otherOpts = Collections.emptyList();
       
   297         List<Path> files = Collections.emptyList();
       
   298         Task.Expect expect = Task.Expect.SUCCESS;
       
   299         String expectedText;
       
   300 
       
   301         /**
       
   302          * Creates a test case, specifying a base directory for work files.
       
   303          */
       
   304         TestCase(Path base) {
       
   305             this.base = base;
       
   306         }
       
   307 
       
   308         /**
       
   309          * Set the "test options" to be passed to javac or to the runtime.
       
   310          */
       
   311         TestCase testOpts(String... testOpts) {
       
   312             this.testOpts = Arrays.asList(testOpts);
       
   313             return this;
       
   314         }
       
   315 
       
   316         /**
       
   317          * Sets additional options required for the compilation.
       
   318          */
       
   319         TestCase otherOpts(String... otherOpts) {
       
   320             this.otherOpts = Arrays.asList(otherOpts);
       
   321             return this;
       
   322         }
       
   323 
       
   324         /**
       
   325          * Sets the files to be compiled.
       
   326          */
       
   327         TestCase files(Path... files) {
       
   328             this.files = Arrays.asList(files);
       
   329             return this;
       
   330         }
       
   331 
       
   332         /**
       
   333          * Sets the expected output, and any expected output from javac.
       
   334          * The default is {@code Expect.SUCCESS} and no specific output expected.
       
   335          */
       
   336         TestCase expect(Task.Expect expect, String expectedText) {
       
   337             this.expect = expect;
       
   338             this.expectedText = expectedText;
       
   339             return this;
       
   340         }
       
   341 
       
   342         /**
       
   343          * Runs the test case.
       
   344          * First, javac is run passing the test options directly to javac.
       
   345          * Then, javac is run again, passing the test options to the runtime,
       
   346          * and using --inherit-runtime-environment.
       
   347          */
       
   348         void run() throws IOException {
       
   349             runJavac();
       
   350             runJava();
       
   351         }
       
   352 
       
   353         private void runJavac() throws IOException {
       
   354             out.println("  javac:");
       
   355             Path javacOutDir = base.resolve("out-javac");
       
   356             Files.createDirectories(javacOutDir);
       
   357 
       
   358             List<String> options = join(testOpts, otherOpts);
       
   359 
       
   360             out.println("    options: " + options);
       
   361             out.println("    outdir: " + javacOutDir);
       
   362             out.println("    files: " + files);
       
   363 
       
   364             String log = new JavacTask(tb, Task.Mode.CMDLINE)
       
   365                     .options(options)
       
   366                     .outdir(javacOutDir)
       
   367                     .files(files)
       
   368                     .run(expect)
       
   369                     .writeAll()
       
   370                     .getOutput(Task.OutputKind.DIRECT);
       
   371 
       
   372             if (expectedText != null && !log.contains(expectedText))
       
   373                 error("expected text not found");
       
   374         }
       
   375 
       
   376         private void runJava() throws IOException {
       
   377             out.println("  java:");
       
   378             Path javaOutDir = base.resolve("out-java");
       
   379             Files.createDirectories(javaOutDir);
       
   380 
       
   381             List<String> vmOpts = join(
       
   382                     testOpts,
       
   383                     Arrays.asList("--module", "jdk.compiler/com.sun.tools.javac.Main")
       
   384             );
       
   385 
       
   386             List<String> classArgs = join(
       
   387                     Arrays.asList("--inherit-runtime-environment",
       
   388                             "-d", javaOutDir.toString()),
       
   389                     otherOpts,
       
   390                     files.stream()
       
   391                             .map(p -> p.toString())
       
   392                             .collect(Collectors.toList())
       
   393             );
       
   394 
       
   395             out.println("    vmOpts: " + vmOpts);
       
   396             out.println("    classArgs: " + classArgs);
       
   397 
       
   398             String log = new JavaTask(tb)
       
   399                     .vmOptions(vmOpts)
       
   400                     .classArgs(classArgs)
       
   401                     .run(expect)
       
   402                     .writeAll()
       
   403                     .getOutput(Task.OutputKind.STDERR);
       
   404 
       
   405             if (expectedText != null && !log.contains(expectedText))
       
   406                 error("expected text not found");
       
   407         }
       
   408     }
       
   409 
       
   410     /**
       
   411      * Join a series of lists.
       
   412      */
       
   413     @SafeVarargs
       
   414     private <T> List<T> join(List<T>... lists) {
       
   415         return Arrays.stream(lists)
       
   416             .flatMap(list -> list.stream())
       
   417             .collect(Collectors.toList());
       
   418     }
       
   419 
       
   420 }
       
   421