ClassPathWithDoubleQuotesTest.java revision 3837:1089212e3333
1162413Ssam/*
2178354Ssam * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
3162413Ssam * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4162413Ssam *
5162413Ssam * This code is free software; you can redistribute it and/or modify it
6162413Ssam * under the terms of the GNU General Public License version 2 only, as
7162413Ssam * published by the Free Software Foundation.
8162413Ssam *
9162413Ssam * This code is distributed in the hope that it will be useful, but WITHOUT
10162413Ssam * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11162413Ssam * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12162413Ssam * version 2 for more details (a copy is included in the LICENSE file that
13162413Ssam * accompanied this code).
14162413Ssam *
15162413Ssam * You should have received a copy of the GNU General Public License version
16162413Ssam * 2 along with this work; if not, write to the Free Software Foundation,
17162413Ssam * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18162413Ssam *
19162413Ssam * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20162413Ssam * or visit www.oracle.com if you need additional information or have any
21162413Ssam * questions.
22162413Ssam */
23162413Ssam
24162413Ssam/**
25162413Ssam * @test
26162413Ssam * @bug 8132562
27162413Ssam * @summary javac fails with CLASSPATH with double-quotes as an environment variable
28162413Ssam * @library /tools/lib
29162413Ssam * @modules jdk.compiler/com.sun.tools.javac.api
30162413Ssam *          jdk.compiler/com.sun.tools.javac.main
31162413Ssam *          jdk.compiler/com.sun.tools.javac.util
32162413Ssam * @build toolbox.ToolBox toolbox.JavacTask
33162413Ssam * @run main ClassPathWithDoubleQuotesTest
34162413Ssam*/
35162413Ssam
36162413Ssamimport java.io.File;
37162413Ssamimport java.nio.file.Path;
38162413Ssamimport java.nio.file.Paths;
39162413Ssam
40162413Ssamimport com.sun.tools.javac.util.Assert;
41162413Ssamimport toolbox.TestRunner;
42162413Ssamimport toolbox.JarTask;
43162413Ssamimport toolbox.JavacTask;
44162413Ssamimport toolbox.Task;
45162413Ssamimport toolbox.ToolBox;
46185522Ssam
47162413Ssampublic class ClassPathWithDoubleQuotesTest extends TestRunner {
48162413Ssam
49162413Ssam    ToolBox tb;
50162413Ssam
51162413Ssam    private static final String ASrc = "public class A { J j; B b;}";
52162413Ssam    private static final String BSrc = "public class B {}";
53162413Ssam    private static final String JarSrc = "public class J {}";
54162413Ssam    private static final String[] jarArgs = {"cf", "test/jarOut/J.jar", "-C", "test/jarSrc", "J.java"};
55162413Ssam    public static final String NEW_LINE = System.getProperty("line.separator");
56162413Ssam    private static final String expectedFailureOutput1 =
57162413Ssam            "A.java:1:18: compiler.err.cant.resolve.location: kindname.class, J, , , (compiler.misc.location: kindname.class, A, null)" + NEW_LINE +
58162413Ssam            "A.java:1:23: compiler.err.cant.resolve.location: kindname.class, B, , , (compiler.misc.location: kindname.class, A, null)" + NEW_LINE +
59185522Ssam            "2 errors" + NEW_LINE;
60162413Ssam    private static final String expectedFailureOutput2A =
61162413Ssam            "- compiler.warn.invalid.path: \"test/jarOut/J.jar" + NEW_LINE +
62162413Ssam            "- compiler.warn.invalid.path: test/src\"" + NEW_LINE +
63162413Ssam            "A.java:1:18: compiler.err.cant.resolve.location: kindname.class, J, , , (compiler.misc.location: kindname.class, A, null)" + NEW_LINE +
64162413Ssam            "A.java:1:23: compiler.err.cant.resolve.location: kindname.class, B, , , (compiler.misc.location: kindname.class, A, null)" + NEW_LINE +
65162413Ssam            "2 errors" + NEW_LINE +
66162413Ssam            "2 warnings" + NEW_LINE;
67162413Ssam    private static final String expectedFailureOutput2B =
68162413Ssam            "- compiler.warn.path.element.not.found: \"test/jarOut/J.jar" + NEW_LINE +
69162413Ssam            "- compiler.warn.path.element.not.found: test/src\"" + NEW_LINE +
70162413Ssam            "A.java:1:18: compiler.err.cant.resolve.location: kindname.class, J, , , (compiler.misc.location: kindname.class, A, null)" + NEW_LINE +
71162413Ssam            "A.java:1:23: compiler.err.cant.resolve.location: kindname.class, B, , , (compiler.misc.location: kindname.class, A, null)" + NEW_LINE +
72162413Ssam            "2 errors" + NEW_LINE +
73162413Ssam            "2 warnings" + NEW_LINE;
74219315Sadrian
75162413Ssam    public static void main(String... args) throws Exception {
76162413Ssam        new ClassPathWithDoubleQuotesTest().runTests();
77162413Ssam    }
78162413Ssam
79223525Sadrian    ClassPathWithDoubleQuotesTest() {
80162413Ssam        super(System.err);
81223525Sadrian        tb = new ToolBox();
82223525Sadrian    }
83223525Sadrian
84223525Sadrian    public void runTests() throws Exception {
85223525Sadrian        runTests(m -> new Object[] { Paths.get(m.getName()) });
86223525Sadrian    }
87223525Sadrian
88162413Ssam    @Test
89162413Ssam    public void test(Path base) throws Exception {
90162413Ssam        Path current = base.resolve(".");
91162413Ssam        Path jarSrc = current.resolve("jarSrc");
92162413Ssam        tb.writeJavaFiles(jarSrc, JarSrc);
93162413Ssam        Path jarOut = current.resolve("jarOut");
94162413Ssam        tb.createDirectories(jarOut);
95162413Ssam        new JarTask(tb).run(jarArgs).writeAll();
96162413Ssam
97162413Ssam        Path src = current.resolve("src");
98162413Ssam        tb.writeJavaFiles(src, ASrc, BSrc);
99196935Ssam
100162413Ssam        /** In any system there can be three possible scenarios:
101162413Ssam         *  1 - The system swallows the problem character (the quote in this case)
102162413Ssam         *      and the test case compiles
103162413Ssam         *  2 - The problem character gets into javac, but it's not bad enough to trigger
104162413Ssam         *      InvalidPathException, but it does mean you can't find the file you're looking for
105162413Ssam         *  3 - The problem character gets into javac and is bad enough to trigger
106162413Ssam         *      InvalidPathException, in which case javac needs to handle the exception in a reasonable way.
107162413Ssam         */
108162413Ssam
109162413Ssam        // testing scenario 1
110162413Ssam        System.err.println("invoking javac EXEC mode without double quotes in the CLASSPATH env variable");
111162413Ssam        new JavacTask(tb, Task.Mode.EXEC)
112162413Ssam                .envVar("CLASSPATH", "test/jarOut/J.jar" + File.pathSeparator + "test/src")
113162413Ssam                .files("test/src/A.java").run(Task.Expect.SUCCESS);
114162413Ssam        System.err.println("successful compilation");
115162413Ssam        System.err.println();
116162413Ssam
117162413Ssam        // testing scenario 2
118162413Ssam        System.err.println("Simulate a system in which double quotes are preserved in the environment variable," +
119162413Ssam                "and for which they are a legal filename character");
120162413Ssam        String log = new JavacTask(tb, Task.Mode.EXEC)
121162413Ssam                .envVar("CLASSPATH", "Ztest/jarOut/J.jar" + File.pathSeparator + "test/srcZ")
122162413Ssam                .options("-XDrawDiagnostics")
123162413Ssam                .files("test/src/A.java").run(Task.Expect.FAIL)
124222031Sadrian                .writeAll()
125222031Sadrian                .getOutput(Task.OutputKind.STDERR);
126222031Sadrian        Assert.check(log.equals(expectedFailureOutput1), "unexpected output");
127162413Ssam        System.err.println("compilation is expected to fail");
128219315Sadrian        System.err.println();
129184369Ssam
130223459Sadrian        // testing scenario 3
131184369Ssam        System.err.println("invoking javac EXEC mode with double quotes in the CLASSPATH env variable");
132184369Ssam        String log2 = new JavacTask(tb, Task.Mode.EXEC)
133184369Ssam                    .envVar("CLASSPATH", "\"test/jarOut/J.jar" + File.pathSeparator + "test/src\"")
134184369Ssam                    .options("-Xlint:path", "-XDrawDiagnostics")
135184369Ssam                    .files("test/src/A.java").run(Task.Expect.FAIL)
136184369Ssam                    .writeAll()
137222031Sadrian                    .getOutput(Task.OutputKind.STDERR);
138162413Ssam        System.err.println();
139162413Ssam        System.err.println("the log:" + log2);
140162413Ssam        Assert.check(log2.equals(expectedFailureOutput2A) || log2.equals(expectedFailureOutput2B),
141162413Ssam                "unexpected output");
142162413Ssam    }
143162413Ssam}
144162413Ssam