|
| 1 | +/* |
| 2 | + * Copyright (c) 2003, 2022, 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 | +/* |
| 26 | + * @test |
| 27 | + * @bug 4758537 4809833 8149599 8293877 |
| 28 | + * @summary Test that javac and java find files in similar ways |
| 29 | + * @library /tools/lib |
| 30 | + * @build toolbox.ToolBox Util MineField |
| 31 | + * @run main MineField |
| 32 | + */ |
| 33 | + |
| 34 | +/* |
| 35 | + * Converted from MineField.sh, originally written by Martin Buchholz. |
| 36 | + * |
| 37 | + * For the last version of the original, MineField.sh, see |
| 38 | + * https://github.com/openjdk/jdk/blob/jdk-19%2B36/test/langtools/tools/javac/Paths/MineField.sh |
| 39 | + * |
| 40 | + * This class primarily tests that javac and the java launcher provide |
| 41 | + * equivalent handling of all path-related options, like {@code -classpath}. |
| 42 | + */ |
| 43 | + |
| 44 | +/* |
| 45 | +#---------------------------------------------------------------- |
| 46 | +# The search order for classes used by both java and javac is: |
| 47 | +# |
| 48 | +# -Xbootclasspath/p:<path> |
| 49 | +# -endorseddirs <dirs> or -Djava.endorsed.dirs=<dirs> (search for jar/zip only) |
| 50 | +# -bootclasspath <path> or -Xbootclasspath:<path> |
| 51 | +# -Xbootclasspath/a:<path> |
| 52 | +# -extdirs <dirs> or -Djava.ext.dirs=<dirs> (search for jar/zip only) |
| 53 | +# -classpath <path>, -cp <path>, env CLASSPATH=<path> |
| 54 | +# |
| 55 | +# Peculiarities of the class file search: |
| 56 | +# - Empty elements of the (user) classpath default to ".", |
| 57 | +# while empty elements of other paths are ignored. |
| 58 | +# - Only for the user classpath is an empty string value equivalent to "." |
| 59 | +# - Specifying a bootclasspath on the command line obliterates any |
| 60 | +# previous -Xbootclasspath/p: or -Xbootclasspath/a: command line flags. |
| 61 | +# |
| 62 | +# JDK 9 update: |
| 63 | +# java: The java launcher does not support any of the following: |
| 64 | +# * -Xbootclasspath/p: -Xbootclasspath: |
| 65 | +# * -endorseddirs -Djava.endorsed.dirs |
| 66 | +# * -extdirs -Djava.ext.dirs |
| 67 | +# All test cases exercising these features have been removed. |
| 68 | +# javac: The following features are only supported when compiling |
| 69 | +# for older releases: |
| 70 | +# * -Xbootclasspath/p: -Xbootclasspath: -bootclasspath -Xbootclasspath/a: |
| 71 | +# * -endorseddirs -Djava.endorsed.dirs |
| 72 | +# * -extdirs -Djava.ext.dirs |
| 73 | +# All test cases exercising these features have been modified to |
| 74 | +# use -source 8 -target 8. In addition, javac test cases involving |
| 75 | +# use of the runtime properties java.endorsed.dirs and java.extdirs |
| 76 | +# (by means of -J-Dname=value) have been removed. |
| 77 | +# Although the primary purpose of the test cases in this file is to |
| 78 | +# compare javac and java behavior, some tests remain for javac for |
| 79 | +# which there is no java equivalent. However, the cases remain as useful |
| 80 | +# test cases for javac handling of the paths involved. |
| 81 | + */ |
| 82 | + |
| 83 | +import java.io.IOException; |
| 84 | +import java.nio.file.Files; |
| 85 | +import java.nio.file.Path; |
| 86 | + |
| 87 | +public class MineField extends Util { |
| 88 | + public static void main(String... args) throws Exception { |
| 89 | + new MineField().run(args); |
| 90 | + } |
| 91 | + |
| 92 | + void run(String... args) throws Exception{ |
| 93 | + setup(); |
| 94 | + tests(); |
| 95 | + cleanup(); |
| 96 | + bottomLine(); |
| 97 | + } |
| 98 | + |
| 99 | + void cleanup() throws IOException { |
| 100 | + deleteFiles("GooSrc", "GooJar", "GooZip", "GooClass"); |
| 101 | + deleteFiles("BadSrc", "BadJar", "BadZip", "BadClass"); |
| 102 | + deleteFiles("OneDir", "Main.java", "MANIFEST.MF"); |
| 103 | + deleteFiles(listFiles(Path.of("."), "*.class")); |
| 104 | + deleteFiles("java-lang.jar"); |
| 105 | + } |
| 106 | + |
| 107 | + /** |
| 108 | + * "Prepare the minefield". |
| 109 | + */ |
| 110 | + void setup() throws Exception { |
| 111 | + cleanup(); |
| 112 | + |
| 113 | + tb.createDirectories("GooSrc", "GooJar", "GooZip", "GooClass"); |
| 114 | + tb.createDirectories("BadSrc", "BadJar", "BadZip", "BadClass"); |
| 115 | + |
| 116 | + Files.writeString(Path.of("Lib.java"), |
| 117 | + "public class Lib {public static void f(){}}"); |
| 118 | + javac("Lib.java"); |
| 119 | + jar("cf", "GooJar/Lib.jar", "Lib.class"); |
| 120 | + jar("cf", "GooZip/Lib.zip", "Lib.class"); |
| 121 | + tb.moveFile("Lib.class", "GooClass/."); |
| 122 | + tb.moveFile("Lib.java", "GooSrc/."); |
| 123 | + checkFiles("GooZip/Lib.zip", "GooJar/Lib.jar", "GooSrc/Lib.java"); |
| 124 | + |
| 125 | + Files.writeString(Path.of("Lib.java"), |
| 126 | + "public class Lib {/* Bad */}"); |
| 127 | + javac("Lib.java"); |
| 128 | + jar("cf", "BadJar/Lib.jar", "Lib.class"); |
| 129 | + jar("cf", "BadZip/Lib.zip", "Lib.class"); |
| 130 | + tb.moveFile("Lib.class", "BadClass/."); |
| 131 | + tb.moveFile("Lib.java", "BadSrc/."); |
| 132 | + checkFiles("BadZip/Lib.zip", "BadJar/Lib.jar", "BadSrc/Lib.java"); |
| 133 | + |
| 134 | + Files.writeString(Path.of("Main.java"), |
| 135 | + "public class Main {public static void main(String[] a) {Lib.f();}}"); |
| 136 | + Path libModules = javaHome.resolve("lib").resolve("modules"); |
| 137 | + if (Files.isReadable(libModules)) { |
| 138 | + jimage("extract", "--dir", "modules", libModules.toString()); |
| 139 | + jar("cf", "java-lang.jar", "-C", "modules/java.base", "java/lang"); |
| 140 | + deleteFiles("modules"); |
| 141 | + } else { |
| 142 | + Path modules = javaHome.resolve("modules"); |
| 143 | + if (Files.isDirectory(modules)) { |
| 144 | + jar("cf", "java-lang.jar", "-C", modules.resolve("java.base").toString(), "java/lang"); |
| 145 | + } else { |
| 146 | + throw new Exception("Cannot create java-lang.jar"); |
| 147 | + } |
| 148 | + } |
| 149 | + } |
| 150 | + |
| 151 | + void tests() throws Exception { |
| 152 | + |
| 153 | + //---------------------------------------------------------------- |
| 154 | + // Verify that javac class search order is the same as java's |
| 155 | + //---------------------------------------------------------------- |
| 156 | + |
| 157 | + expectFail(JAVAC, """ |
| 158 | + -source 8 -target 8 |
| 159 | + -Xbootclasspath/p:GooClass |
| 160 | + -bootclasspath java-lang.jar${PS}BadZip/Lib.zip |
| 161 | + Main.java"""); |
| 162 | + |
| 163 | + expectPass(JAVAC, """ |
| 164 | + -source 8 -target 8 |
| 165 | + -Xbootclasspath/p:BadClass${PS}GooClass |
| 166 | + -bootclasspath java-lang.jar${PS}GooZip/Lib.zip${PS}BadClass |
| 167 | + Main.java"""); |
| 168 | + |
| 169 | + expectPass(JAVAC, """ |
| 170 | + -source 8 -target 8 |
| 171 | + -Xbootclasspath/p:BadJar/Lib.jar |
| 172 | + -Xbootclasspath:java-lang.jar${PS}GooClass |
| 173 | + Main.java"""); |
| 174 | + |
| 175 | + //---------------------------------------------------------------- |
| 176 | + |
| 177 | + expectFail(JAVAC, """ |
| 178 | + -source 8 -target 8 |
| 179 | + -bootclasspath java-lang.jar${PS}GooZip/Lib.zip |
| 180 | + -Xbootclasspath/p:BadClass |
| 181 | + Main.java"""); |
| 182 | + |
| 183 | + expectPass(JAVAC, """ |
| 184 | + -source 8 -target 8 |
| 185 | + -bootclasspath java-lang.jar${PS}BadZip/Lib.zip |
| 186 | + -Xbootclasspath/p:GooClass${PS}BadJar/Lib.jar |
| 187 | + Main.java"""); |
| 188 | + |
| 189 | + //---------------------------------------------------------------- |
| 190 | + |
| 191 | + expectFail(JAVAC, """ |
| 192 | + -source 8 -target 8 |
| 193 | + -Xbootclasspath/p:BadClass |
| 194 | + -Xbootclasspath/a:GooClass |
| 195 | + Main.java"""); |
| 196 | + |
| 197 | + expectPass(JAVAC, """ |
| 198 | + -source 8 -target 8 |
| 199 | + -Xbootclasspath/p:GooClass${PS}BadClass |
| 200 | + -Xbootclasspath/a:BadClass |
| 201 | + Main.java"""); |
| 202 | + |
| 203 | + expectPass(JAVA, """ |
| 204 | + -Xbootclasspath/a:GooClass |
| 205 | + Main"""); |
| 206 | + |
| 207 | + //---------------------------------------------------------------- |
| 208 | + |
| 209 | + expectFail(JAVAC, """ |
| 210 | + -source 8 -target 8 |
| 211 | + -Xbootclasspath/p:GooClass |
| 212 | + -Xbootclasspath:BadClass${PS}java-lang.jar |
| 213 | + -Xbootclasspath/a:GooClass |
| 214 | + Main.java"""); |
| 215 | + |
| 216 | + expectPass(JAVAC, """ |
| 217 | + -source 8 -target 8 |
| 218 | + -Xbootclasspath/p:BadClass |
| 219 | + -Xbootclasspath:GooClass${PS}BadClass${PS}java-lang.jar |
| 220 | + -Xbootclasspath/a:BadClass |
| 221 | + Main.java"""); |
| 222 | + |
| 223 | + //---------------------------------------------------------------- |
| 224 | + |
| 225 | + expectPass(JAVAC, """ |
| 226 | + -source 8 -target 8 |
| 227 | + -endorseddirs BadClass${PS}GooZip${PS}BadJar |
| 228 | + -Xbootclasspath:"BadClass${PS}java-lang.jar |
| 229 | + Main.java"""); |
| 230 | + |
| 231 | + expectPass(JAVAC, """ |
| 232 | + -source 8 -target 8 |
| 233 | + -Djava.endorsed.dirs=BadClass${PS}GooZip${PS}BadJar |
| 234 | + -Xbootclasspath:BadClass${PS}java-lang.jar |
| 235 | + Main.java"""); |
| 236 | + |
| 237 | + //---------------------------------------------------------------- |
| 238 | + |
| 239 | + expectFail(JAVAC, """ |
| 240 | + -source 8 -target 8 |
| 241 | + -Xbootclasspath/a:BadClass |
| 242 | + -extdirs GooZip |
| 243 | + Main.java"""); |
| 244 | + |
| 245 | + expectPass(JAVAC, """ |
| 246 | + -source 8 -target 8 |
| 247 | + -Xbootclasspath/a:GooClass${PS}BadClass |
| 248 | + -extdirs BadZip |
| 249 | + Main.java"""); |
| 250 | + |
| 251 | + //---------------------------------------------------------------- |
| 252 | + |
| 253 | + expectFail(JAVAC, """ |
| 254 | + -source 8 -target 8 |
| 255 | + -extdirs GooClass${PS}BadZip |
| 256 | + -cp GooZip/Lib.zip |
| 257 | + Main.java"""); |
| 258 | + |
| 259 | + expectPass(JAVAC, """ |
| 260 | + -source 8 -target 8 |
| 261 | + -extdirs BadClass${PS}GooZip${PS}BadJar |
| 262 | + -cp BadZip/Lib.zip |
| 263 | + Main.java"""); |
| 264 | + |
| 265 | + expectPass(JAVAC, """ |
| 266 | + -source 8 -target 8 |
| 267 | + -Djava.ext.dirs=GooZip${PS}BadJar |
| 268 | + -classpath BadZip/Lib.zip |
| 269 | + Main.java"""); |
| 270 | + |
| 271 | + //---------------------------------------------------------------- |
| 272 | + |
| 273 | + expectFail(JAVAC, "-classpath BadClass${PS}GooClass Main.java"); |
| 274 | + expectPass(JAVAC, "-classpath GooClass${PS}BadClass Main.java"); |
| 275 | + expectFail(JAVA, "-classpath BadClass${PS}GooClass${PS}. Main"); |
| 276 | + expectPass(JAVA, "-classpath GooClass${PS}BadClass${PS}. Main"); |
| 277 | + |
| 278 | + expectFail(JAVAC, "-cp BadJar/Lib.jar${PS}GooZip/Lib.zip Main.java"); |
| 279 | + expectPass(JAVAC, "-cp GooJar/Lib.jar${PS}BadZip/Lib.zip Main.java"); |
| 280 | + expectFail(JAVA, "-cp BadJar/Lib.jar${PS}${PS}GooZip/Lib.zip Main"); |
| 281 | + expectPass(JAVA, "-cp GooJar/Lib.jar${PS}${PS}BadZip/Lib.zip Main"); |
| 282 | + |
| 283 | + //---------------------------------------------------------------- |
| 284 | + |
| 285 | + expectFail(classpath("BadZip/Lib.zip${PS}GooJar/Lib.jar"), JAVAC,"Main.java"); |
| 286 | + expectPass(classpath("GooZip/Lib.zip${PS}BadJar/Lib.jar"), JAVAC, "Main.java"); |
| 287 | + expectFail(classpath("${PS}BadZip/Lib.zip${PS}GooJar/Lib.jar"), JAVA, "Main"); |
| 288 | + expectPass(classpath("${PS}GooZip/Lib.zip${PS}BadJar/Lib.jar"), JAVA, "Main"); |
| 289 | + |
| 290 | + //---------------------------------------------------------------- |
| 291 | + // Check behavior of empty paths and empty path elements |
| 292 | + //---------------------------------------------------------------- |
| 293 | + |
| 294 | + Path GooClass = Path.of("GooClass"); |
| 295 | + Path GooJar = Path.of("GooJar"); |
| 296 | + |
| 297 | + expectFail(GooClass, JAVAC, "-cp .. ../Main.java"); |
| 298 | + expectFail(GooClass, JAVA, "-cp .. Main"); |
| 299 | + |
| 300 | + // Unspecified classpath defaults to "." |
| 301 | + Path OneDir = Path.of("OneDir"); |
| 302 | + tb.createDirectories(OneDir); |
| 303 | + tb.copyFile(Path.of("Main.java"), OneDir); |
| 304 | + tb.copyFile(GooClass.resolve("Lib.class"), OneDir); |
| 305 | + expectPass(OneDir, JAVAC, "Main.java"); |
| 306 | + expectPass(OneDir, JAVA, "Main"); |
| 307 | + |
| 308 | + // Empty classpath elements mean "." |
| 309 | + expectPass(GooClass, JAVAC, "-cp ${PS}.. ../Main.java"); |
| 310 | + expectPass(GooClass, JAVA, "-cp ${PS}.. Main"); |
| 311 | + |
| 312 | + expectPass(GooClass, JAVAC, "-cp ..${PS} ../Main.java"); |
| 313 | + expectPass(GooClass, JAVA, "-cp ..${PS} Main"); |
| 314 | + |
| 315 | + expectPass(GooClass, JAVAC, "-cp ..${PS}${PS}/xyzzy ../Main.java"); |
| 316 | + expectPass(GooClass, JAVA, "-cp ..${PS}${PS}/xyzzy Main"); |
| 317 | + |
| 318 | + // All other empty path elements are ignored. |
| 319 | + |
| 320 | + // note presence of empty arg in this invocation |
| 321 | + expectFail(GooJar, null, JAVAC, "-source", "8", "-target", "8", "-extdirs", "", "-cp", "..", "../Main.java"); |
| 322 | + |
| 323 | + expectFail(GooJar, JAVAC, "-source 8 -target 8 -extdirs ${PS} -cp .. ../Main.java"); |
| 324 | + expectFail(GooJar, JAVAC, "-source 8 -target 8 -Djava.ext.dirs=${PS} -cp .. ../Main.java"); |
| 325 | + |
| 326 | + expectPass(GooJar, JAVAC, "-source 8 -target 8 -extdirs . -cp .. ../Main.java"); |
| 327 | + expectPass(GooJar, JAVAC, "-source 8 -target 8 -Djava.ext.dirs=. -cp .. ../Main.java"); |
| 328 | + |
| 329 | + expectFail(GooJar, JAVAC, "-source 8 -target 8 -Djava.endorsed.dirs= -cp .. ../Main.java"); |
| 330 | + |
| 331 | + expectFail(GooJar, JAVAC, "-source 8 -target 8 -endorseddirs ${PS} -cp .. ../Main.java"); |
| 332 | + |
| 333 | + expectPass(GooJar, JAVAC, "-source 8 -target 8 -Djava.endorsed.dirs=. -cp .. ../Main.java"); |
| 334 | + |
| 335 | + expectFail(GooClass, JAVAC, "-source 8 -target 8 -Xbootclasspath/p: -cp .. ../Main.java"); |
| 336 | + |
| 337 | + expectPass(GooClass, JAVAC, "-source 8 -target 8 -Xbootclasspath/p:. -cp .. ../Main.java"); |
| 338 | + |
| 339 | + expectFail(GooClass, JAVAC, "-source 8 -target 8 -Xbootclasspath:../java-lang.jar -cp .. ../Main.java"); |
| 340 | + |
| 341 | + expectPass(GooClass, JAVAC, "-source 8 -target 8 -Xbootclasspath:../java-lang.jar${PS}. -cp .. ../Main.java"); |
| 342 | + |
| 343 | + expectFail(GooClass, JAVAC, "-source 8 -target 8 -Xbootclasspath/a: -cp .. ../Main.java"); |
| 344 | + expectFail(GooClass, JAVA, "-Xbootclasspath/a: -cp .. Main"); |
| 345 | + |
| 346 | + expectPass(GooClass, JAVAC, "-source 8 -target 8 -Xbootclasspath/a:. -cp .. ../Main.java"); |
| 347 | + expectPass(GooClass, JAVA, "-Xbootclasspath/a:. -cp .. Main"); |
| 348 | + |
| 349 | + } |
| 350 | + |
| 351 | + |
| 352 | +} |
1 commit comments
openjdk-notifier[bot] commentedon Sep 10, 2024
Review
Issues