26 * @bug 8132562 |
26 * @bug 8132562 |
27 * @summary javac fails with CLASSPATH with double-quotes as an environment variable |
27 * @summary javac fails with CLASSPATH with double-quotes as an environment variable |
28 * @library /tools/lib |
28 * @library /tools/lib |
29 * @modules jdk.compiler/com.sun.tools.javac.api |
29 * @modules jdk.compiler/com.sun.tools.javac.api |
30 * jdk.compiler/com.sun.tools.javac.main |
30 * jdk.compiler/com.sun.tools.javac.main |
|
31 * jdk.compiler/com.sun.tools.javac.util |
31 * @build toolbox.ToolBox toolbox.JavacTask |
32 * @build toolbox.ToolBox toolbox.JavacTask |
32 * @run main ClassPathWithDoubleQuotesTest |
33 * @run main ClassPathWithDoubleQuotesTest |
33 */ |
34 */ |
34 |
35 |
35 import java.io.File; |
36 import java.io.File; |
36 import java.nio.file.Path; |
37 import java.nio.file.Path; |
37 import java.nio.file.Paths; |
38 import java.nio.file.Paths; |
38 |
39 |
|
40 import com.sun.tools.javac.util.Assert; |
39 import toolbox.TestRunner; |
41 import toolbox.TestRunner; |
40 import toolbox.JarTask; |
42 import toolbox.JarTask; |
41 import toolbox.JavacTask; |
43 import toolbox.JavacTask; |
42 import toolbox.Task; |
44 import toolbox.Task; |
43 import toolbox.ToolBox; |
45 import toolbox.ToolBox; |
44 |
46 |
45 public class ClassPathWithDoubleQuotesTest extends TestRunner { |
47 public class ClassPathWithDoubleQuotesTest extends TestRunner { |
46 |
48 |
47 ToolBox tb; |
49 ToolBox tb; |
48 |
50 |
49 private static final String ASrc = "public class A {}"; |
51 private static final String ASrc = "public class A { J j; B b;}"; |
|
52 private static final String BSrc = "public class B {}"; |
50 private static final String JarSrc = "public class J {}"; |
53 private static final String JarSrc = "public class J {}"; |
51 private static final String[] jarArgs = {"cf", "test/J.jar", "-C", "test", "J.java"}; |
54 private static final String[] jarArgs = {"cf", "test/jarOut/J.jar", "-C", "test/jarSrc", "J.java"}; |
|
55 public static final String NEW_LINE = System.getProperty("line.separator"); |
|
56 private static final String expectedFailureOutput1 = |
|
57 "A.java:1:18: compiler.err.cant.resolve.location: kindname.class, J, , , (compiler.misc.location: kindname.class, A, null)" + NEW_LINE + |
|
58 "A.java:1:23: compiler.err.cant.resolve.location: kindname.class, B, , , (compiler.misc.location: kindname.class, A, null)" + NEW_LINE + |
|
59 "2 errors" + NEW_LINE; |
|
60 private static final String expectedFailureOutput2A = |
|
61 "- compiler.warn.invalid.path: \"test/jarOut/J.jar" + NEW_LINE + |
|
62 "- compiler.warn.invalid.path: test/src\"" + NEW_LINE + |
|
63 "A.java:1:18: compiler.err.cant.resolve.location: kindname.class, J, , , (compiler.misc.location: kindname.class, A, null)" + NEW_LINE + |
|
64 "A.java:1:23: compiler.err.cant.resolve.location: kindname.class, B, , , (compiler.misc.location: kindname.class, A, null)" + NEW_LINE + |
|
65 "2 errors" + NEW_LINE + |
|
66 "2 warnings" + NEW_LINE; |
|
67 private static final String expectedFailureOutput2B = |
|
68 "- compiler.warn.path.element.not.found: \"test/jarOut/J.jar" + NEW_LINE + |
|
69 "- compiler.warn.path.element.not.found: test/src\"" + NEW_LINE + |
|
70 "A.java:1:18: compiler.err.cant.resolve.location: kindname.class, J, , , (compiler.misc.location: kindname.class, A, null)" + NEW_LINE + |
|
71 "A.java:1:23: compiler.err.cant.resolve.location: kindname.class, B, , , (compiler.misc.location: kindname.class, A, null)" + NEW_LINE + |
|
72 "2 errors" + NEW_LINE + |
|
73 "2 warnings" + NEW_LINE; |
52 |
74 |
53 public static void main(String... args) throws Exception { |
75 public static void main(String... args) throws Exception { |
54 new ClassPathWithDoubleQuotesTest().runTests(); |
76 new ClassPathWithDoubleQuotesTest().runTests(); |
55 } |
77 } |
56 |
78 |
64 } |
86 } |
65 |
87 |
66 @Test |
88 @Test |
67 public void test(Path base) throws Exception { |
89 public void test(Path base) throws Exception { |
68 Path current = base.resolve("."); |
90 Path current = base.resolve("."); |
69 tb.writeJavaFiles(current, ASrc, JarSrc); |
91 Path jarSrc = current.resolve("jarSrc"); |
|
92 tb.writeJavaFiles(jarSrc, JarSrc); |
|
93 Path jarOut = current.resolve("jarOut"); |
|
94 tb.createDirectories(jarOut); |
70 new JarTask(tb).run(jarArgs).writeAll(); |
95 new JarTask(tb).run(jarArgs).writeAll(); |
71 |
96 |
72 executeTask(new JavacTask(tb, Task.Mode.EXEC) |
97 Path src = current.resolve("src"); |
73 .envVar("CLASSPATH", "\"test/J.jar" + File.pathSeparator + "test\"") |
98 tb.writeJavaFiles(src, ASrc, BSrc); |
74 .files("test/A.java")); |
|
75 |
99 |
76 executeTask(new JavacTask(tb) |
100 /** In any system there can be three possible scenarios: |
77 .classpath("\"test/J.jar" + File.pathSeparator + "test\"") |
101 * 1 - The system swallows the problem character (the quote in this case) |
78 .files("test/A.java")); |
102 * and the test case compiles |
79 } |
103 * 2 - The problem character gets into javac, but it's not bad enough to trigger |
|
104 * InvalidPathException, but it does mean you can't find the file you're looking for |
|
105 * 3 - The problem character gets into javac and is bad enough to trigger |
|
106 * InvalidPathException, in which case javac needs to handle the exception in a reasonable way. |
|
107 */ |
80 |
108 |
81 void executeTask(JavacTask task) { |
109 // testing scenario 1 |
82 boolean isWindows = System.getProperty("os.name").startsWith("Windows"); |
110 System.err.println("invoking javac EXEC mode without double quotes in the CLASSPATH env variable"); |
83 Task.Expect whatToExpect = isWindows ? Task.Expect.FAIL : Task.Expect.SUCCESS; |
111 new JavacTask(tb, Task.Mode.EXEC) |
84 try { |
112 .envVar("CLASSPATH", "test/jarOut/J.jar" + File.pathSeparator + "test/src") |
85 task.run(whatToExpect); |
113 .files("test/src/A.java").run(Task.Expect.SUCCESS); |
86 if (isWindows) { |
114 System.err.println("successful compilation"); |
87 throw new AssertionError("exception must be thrown"); |
115 System.err.println(); |
88 } |
116 |
89 } catch (IllegalArgumentException iae) { |
117 // testing scenario 2 |
90 if (!isWindows) { |
118 System.err.println("Simulate a system in which double quotes are preserved in the environment variable," + |
91 throw new AssertionError("exception unexpectedly thrown"); |
119 "and for which they are a legal filename character"); |
92 } |
120 String log = new JavacTask(tb, Task.Mode.EXEC) |
93 } catch (Throwable t) { |
121 .envVar("CLASSPATH", "Ztest/jarOut/J.jar" + File.pathSeparator + "test/srcZ") |
94 throw new AssertionError("unexpected exception thrown"); |
122 .options("-XDrawDiagnostics") |
95 } |
123 .files("test/src/A.java").run(Task.Expect.FAIL) |
|
124 .writeAll() |
|
125 .getOutput(Task.OutputKind.STDERR); |
|
126 Assert.check(log.equals(expectedFailureOutput1), "unexpected output"); |
|
127 System.err.println("compilation is expected to fail"); |
|
128 System.err.println(); |
|
129 |
|
130 // testing scenario 3 |
|
131 System.err.println("invoking javac EXEC mode with double quotes in the CLASSPATH env variable"); |
|
132 String log2 = new JavacTask(tb, Task.Mode.EXEC) |
|
133 .envVar("CLASSPATH", "\"test/jarOut/J.jar" + File.pathSeparator + "test/src\"") |
|
134 .options("-Xlint:path", "-XDrawDiagnostics") |
|
135 .files("test/src/A.java").run(Task.Expect.FAIL) |
|
136 .writeAll() |
|
137 .getOutput(Task.OutputKind.STDERR); |
|
138 System.err.println(); |
|
139 System.err.println("the log:" + log2); |
|
140 Assert.check(log2.equals(expectedFailureOutput2A) || log2.equals(expectedFailureOutput2B), |
|
141 "unexpected output"); |
96 } |
142 } |
97 } |
143 } |