1 /* 2 * Copyright (c) 2016, 2017, 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 import java.io.BufferedWriter; 25 import java.nio.file.Files; 26 import java.nio.file.Path; 27 import java.nio.file.Paths; 28 import java.util.ArrayList; 29 import java.util.List; 30 import java.util.Map; 31 import java.util.spi.ToolProvider; 32 import java.util.stream.Stream; 33 34 import jdk.test.lib.JDKToolFinder; 35 import jdk.test.lib.Platform; 36 import jdk.test.lib.compiler.CompilerUtils; 37 import jdk.test.lib.process.OutputAnalyzer; 38 import org.testng.annotations.BeforeTest; 39 import org.testng.annotations.DataProvider; 40 import org.testng.annotations.Test; 41 42 import static org.testng.Assert.assertTrue; 43 import static jdk.test.lib.process.ProcessTools.*; 44 45 /** 46 * @test 47 * @bug 8168205 48 * @summary Test the default class path if -Djava.class.path is set 49 * @library /test/lib 50 * @modules jdk.compiler 51 * jdk.jartool 52 * @build jdk.test.lib.compiler.CompilerUtils 53 * @run testng JavaClassPathTest 54 */ 55 56 public class JavaClassPathTest { 57 private static final Path SRC_DIR = Paths.get(System.getProperty("test.src"), 58 "src"); 59 private static final Path MODS_DIR = Paths.get("mods"); 60 private static final Path LIB_DIR = Paths.get("lib"); 61 private static final String TEST_MODULE = "m"; 62 private static final String TEST_MAIN = "jdk.test.Main"; 63 64 @BeforeTest 65 public void setup() throws Exception { 66 boolean compiled = CompilerUtils.compile(SRC_DIR.resolve(TEST_MODULE), 67 MODS_DIR.resolve(TEST_MODULE)); 68 assertTrue(compiled, "module " + TEST_MODULE + " did not compile"); 69 70 // add the class and a resource to the current working directory 71 Path file = Paths.get("jdk/test/Main.class"); 72 Files.createDirectories(file.getParent()); 73 Files.copy(MODS_DIR.resolve(TEST_MODULE).resolve(file), file); 74 75 Path res = Paths.get("jdk/test/res.properties"); 76 Files.createFile(res); 77 78 ToolProvider jartool = ToolProvider.findFirst("jar").orElseThrow( 79 () -> new RuntimeException("jar tool not found") 80 ); 81 82 Path jarfile = LIB_DIR.resolve("m.jar"); 83 Files.createDirectories(LIB_DIR); 84 assertTrue(jartool.run(System.out, System.err, "cfe", 85 jarfile.toString(), TEST_MAIN, 86 file.toString()) == 0); 87 88 Path manifest = LIB_DIR.resolve("manifest"); 89 try (BufferedWriter writer = Files.newBufferedWriter(manifest)) { 90 writer.write("CLASS-PATH: lib/m.jar"); 91 } 92 jarfile = LIB_DIR.resolve("m1.jar"); 93 assertTrue(jartool.run(System.out, System.err, "cfme", 94 jarfile.toString(), manifest.toString(), TEST_MAIN, 95 file.toString()) == 0); 96 } 97 98 @DataProvider(name = "classpath") 99 public Object[][] classpath() { 100 return new Object[][]{ 101 // true indicates that class path default to current working directory 102 { List.of(), "." }, 103 { List.of("-cp", ""), "" }, 104 { List.of("-cp", "."), "." }, 105 { List.of("-Djava.class.path"), "." }, 106 { List.of("-Djava.class.path="), "" }, 107 { List.of("-Djava.class.path=."), "." }, 108 }; 109 } 110 111 @Test(dataProvider = "classpath") 112 public void testUnnamedModule(List<String> options, String expected) 113 throws Throwable 114 { 115 List<String> args = new ArrayList<>(options); 116 args.add(TEST_MAIN); 117 args.add(Boolean.toString(true)); 118 args.add(expected); 119 120 assertTrue(execute(args).getExitValue() == 0); 121 } 122 123 @DataProvider(name = "moduleAndClassPath") 124 public Object[][] moduleAndClassPath() { 125 return new Object[][]{ 126 // true indicates that class path default to current working directory 127 { "", "" }, 128 { "-Djava.class.path", "" }, 129 { "-Djava.class.path=", "" }, 130 }; 131 } 132 133 @Test(dataProvider = "moduleAndClassPath") 134 public void testNamedModule(String option, String expected) throws Throwable { 135 List<String> args = new ArrayList<>(); 136 if (!option.isEmpty()) { 137 args.add(option); 138 } 139 args.add("--module-path"); 140 args.add(MODS_DIR.toString()); 141 args.add("-m"); 142 args.add(TEST_MODULE + "/" + TEST_MAIN); 143 // not default to CWD 144 args.add(Boolean.toString(false)); 145 args.add(expected); 146 147 148 assertTrue(execute(args).getExitValue() == 0); 149 } 150 151 @Test 152 public void testClassPath() throws Throwable { 153 List<String> args = new ArrayList<>(); 154 args.add("-Djava.class.path=."); 155 args.add("--module-path"); 156 args.add(MODS_DIR.toString()); 157 args.add("-m"); 158 args.add(TEST_MODULE + "/" + TEST_MAIN); 159 args.add(Boolean.toString(true)); 160 args.add("."); 161 162 assertTrue(execute(args).getExitValue() == 0); 163 } 164 165 @Test 166 public void testJAR() throws Throwable { 167 String jarfile = LIB_DIR.resolve("m.jar").toString(); 168 List<String> args = new ArrayList<>(); 169 args.add("-jar"); 170 args.add(jarfile); 171 args.add(Boolean.toString(false)); 172 args.add(jarfile); 173 174 assertTrue(execute(args).getExitValue() == 0); 175 } 176 177 /* 178 * Test CLASS-PATH attribute in manifest 179 */ 180 @Test 181 public void testClassPathAttribute() throws Throwable { 182 String jarfile = LIB_DIR.resolve("m1.jar").toString(); 183 184 List<String> args = new ArrayList<>(); 185 args.add("-jar"); 186 args.add(jarfile); 187 args.add(Boolean.toString(false)); 188 args.add(jarfile); 189 190 assertTrue(execute(args).getExitValue() == 0); 191 192 args.clear(); 193 args.add("-cp"); 194 args.add(jarfile); 195 args.add(TEST_MAIN); 196 args.add(Boolean.toString(false)); 197 args.add(jarfile); 198 199 assertTrue(execute(args).getExitValue() == 0); 200 } 201 202 private OutputAnalyzer execute(List<String> options) throws Throwable { 203 // can't use ProcessTools.createJavaProcessBuilder as it always adds -cp 204 ProcessBuilder pb = new ProcessBuilder( 205 Stream.concat(Stream.of(JDKToolFinder.getTestJDKTool("java")), 206 options.stream() 207 .map(this::autoQuote)) 208 .toArray(String[]::new) 209 ); 210 211 Map<String,String> env = pb.environment(); 212 // remove CLASSPATH environment variable 213 env.remove("CLASSPATH"); 214 return executeCommand(pb) 215 .outputTo(System.out) 216 .errorTo(System.out); 217 } 218 219 /* 220 * Autoquote empty string argument on Windows 221 */ 222 private String autoQuote(String arg) { 223 if (Platform.isWindows() && arg.isEmpty()) { 224 return "\"\""; 225 } 226 return arg; 227 } 228 }