jdk-24/test/langtools/tools/javac/Paths/MineField.java
Jonathan Gibbons 090cdfc7a2 8294726: Update URLs in minefield tests
Reviewed-by: darcy, iris
2022-10-03 20:20:53 +00:00

353 lines
14 KiB
Java

/*
* Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4758537 4809833 8149599 8293877
* @summary Test that javac and java find files in similar ways
* @library /tools/lib
* @build toolbox.ToolBox Util MineField
* @run main MineField
*/
/*
* Converted from MineField.sh, originally written by Martin Buchholz.
*
* For the last version of the original, MineField.sh, see
* https://git.openjdk.org/jdk/blob/jdk-19%2B36/test/langtools/tools/javac/Paths/MineField.sh
*
* This class primarily tests that javac and the java launcher provide
* equivalent handling of all path-related options, like {@code -classpath}.
*/
/*
#----------------------------------------------------------------
# The search order for classes used by both java and javac is:
#
# -Xbootclasspath/p:<path>
# -endorseddirs <dirs> or -Djava.endorsed.dirs=<dirs> (search for jar/zip only)
# -bootclasspath <path> or -Xbootclasspath:<path>
# -Xbootclasspath/a:<path>
# -extdirs <dirs> or -Djava.ext.dirs=<dirs> (search for jar/zip only)
# -classpath <path>, -cp <path>, env CLASSPATH=<path>
#
# Peculiarities of the class file search:
# - Empty elements of the (user) classpath default to ".",
# while empty elements of other paths are ignored.
# - Only for the user classpath is an empty string value equivalent to "."
# - Specifying a bootclasspath on the command line obliterates any
# previous -Xbootclasspath/p: or -Xbootclasspath/a: command line flags.
#
# JDK 9 update:
# java: The java launcher does not support any of the following:
# * -Xbootclasspath/p: -Xbootclasspath:
# * -endorseddirs -Djava.endorsed.dirs
# * -extdirs -Djava.ext.dirs
# All test cases exercising these features have been removed.
# javac: The following features are only supported when compiling
# for older releases:
# * -Xbootclasspath/p: -Xbootclasspath: -bootclasspath -Xbootclasspath/a:
# * -endorseddirs -Djava.endorsed.dirs
# * -extdirs -Djava.ext.dirs
# All test cases exercising these features have been modified to
# use -source 8 -target 8. In addition, javac test cases involving
# use of the runtime properties java.endorsed.dirs and java.extdirs
# (by means of -J-Dname=value) have been removed.
# Although the primary purpose of the test cases in this file is to
# compare javac and java behavior, some tests remain for javac for
# which there is no java equivalent. However, the cases remain as useful
# test cases for javac handling of the paths involved.
*/
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class MineField extends Util {
public static void main(String... args) throws Exception {
new MineField().run(args);
}
void run(String... args) throws Exception{
setup();
tests();
cleanup();
bottomLine();
}
void cleanup() throws IOException {
deleteFiles("GooSrc", "GooJar", "GooZip", "GooClass");
deleteFiles("BadSrc", "BadJar", "BadZip", "BadClass");
deleteFiles("OneDir", "Main.java", "MANIFEST.MF");
deleteFiles(listFiles(Path.of("."), "*.class"));
deleteFiles("java-lang.jar");
}
/**
* "Prepare the minefield".
*/
void setup() throws Exception {
cleanup();
tb.createDirectories("GooSrc", "GooJar", "GooZip", "GooClass");
tb.createDirectories("BadSrc", "BadJar", "BadZip", "BadClass");
Files.writeString(Path.of("Lib.java"),
"public class Lib {public static void f(){}}");
javac("Lib.java");
jar("cf", "GooJar/Lib.jar", "Lib.class");
jar("cf", "GooZip/Lib.zip", "Lib.class");
tb.moveFile("Lib.class", "GooClass/.");
tb.moveFile("Lib.java", "GooSrc/.");
checkFiles("GooZip/Lib.zip", "GooJar/Lib.jar", "GooSrc/Lib.java");
Files.writeString(Path.of("Lib.java"),
"public class Lib {/* Bad */}");
javac("Lib.java");
jar("cf", "BadJar/Lib.jar", "Lib.class");
jar("cf", "BadZip/Lib.zip", "Lib.class");
tb.moveFile("Lib.class", "BadClass/.");
tb.moveFile("Lib.java", "BadSrc/.");
checkFiles("BadZip/Lib.zip", "BadJar/Lib.jar", "BadSrc/Lib.java");
Files.writeString(Path.of("Main.java"),
"public class Main {public static void main(String[] a) {Lib.f();}}");
Path libModules = javaHome.resolve("lib").resolve("modules");
if (Files.isReadable(libModules)) {
jimage("extract", "--dir", "modules", libModules.toString());
jar("cf", "java-lang.jar", "-C", "modules/java.base", "java/lang");
deleteFiles("modules");
} else {
Path modules = javaHome.resolve("modules");
if (Files.isDirectory(modules)) {
jar("cf", "java-lang.jar", "-C", modules.resolve("java.base").toString(), "java/lang");
} else {
throw new Exception("Cannot create java-lang.jar");
}
}
}
void tests() throws Exception {
//----------------------------------------------------------------
// Verify that javac class search order is the same as java's
//----------------------------------------------------------------
expectFail(JAVAC, """
-source 8 -target 8
-Xbootclasspath/p:GooClass
-bootclasspath java-lang.jar${PS}BadZip/Lib.zip
Main.java""");
expectPass(JAVAC, """
-source 8 -target 8
-Xbootclasspath/p:BadClass${PS}GooClass
-bootclasspath java-lang.jar${PS}GooZip/Lib.zip${PS}BadClass
Main.java""");
expectPass(JAVAC, """
-source 8 -target 8
-Xbootclasspath/p:BadJar/Lib.jar
-Xbootclasspath:java-lang.jar${PS}GooClass
Main.java""");
//----------------------------------------------------------------
expectFail(JAVAC, """
-source 8 -target 8
-bootclasspath java-lang.jar${PS}GooZip/Lib.zip
-Xbootclasspath/p:BadClass
Main.java""");
expectPass(JAVAC, """
-source 8 -target 8
-bootclasspath java-lang.jar${PS}BadZip/Lib.zip
-Xbootclasspath/p:GooClass${PS}BadJar/Lib.jar
Main.java""");
//----------------------------------------------------------------
expectFail(JAVAC, """
-source 8 -target 8
-Xbootclasspath/p:BadClass
-Xbootclasspath/a:GooClass
Main.java""");
expectPass(JAVAC, """
-source 8 -target 8
-Xbootclasspath/p:GooClass${PS}BadClass
-Xbootclasspath/a:BadClass
Main.java""");
expectPass(JAVA, """
-Xbootclasspath/a:GooClass
Main""");
//----------------------------------------------------------------
expectFail(JAVAC, """
-source 8 -target 8
-Xbootclasspath/p:GooClass
-Xbootclasspath:BadClass${PS}java-lang.jar
-Xbootclasspath/a:GooClass
Main.java""");
expectPass(JAVAC, """
-source 8 -target 8
-Xbootclasspath/p:BadClass
-Xbootclasspath:GooClass${PS}BadClass${PS}java-lang.jar
-Xbootclasspath/a:BadClass
Main.java""");
//----------------------------------------------------------------
expectPass(JAVAC, """
-source 8 -target 8
-endorseddirs BadClass${PS}GooZip${PS}BadJar
-Xbootclasspath:"BadClass${PS}java-lang.jar
Main.java""");
expectPass(JAVAC, """
-source 8 -target 8
-Djava.endorsed.dirs=BadClass${PS}GooZip${PS}BadJar
-Xbootclasspath:BadClass${PS}java-lang.jar
Main.java""");
//----------------------------------------------------------------
expectFail(JAVAC, """
-source 8 -target 8
-Xbootclasspath/a:BadClass
-extdirs GooZip
Main.java""");
expectPass(JAVAC, """
-source 8 -target 8
-Xbootclasspath/a:GooClass${PS}BadClass
-extdirs BadZip
Main.java""");
//----------------------------------------------------------------
expectFail(JAVAC, """
-source 8 -target 8
-extdirs GooClass${PS}BadZip
-cp GooZip/Lib.zip
Main.java""");
expectPass(JAVAC, """
-source 8 -target 8
-extdirs BadClass${PS}GooZip${PS}BadJar
-cp BadZip/Lib.zip
Main.java""");
expectPass(JAVAC, """
-source 8 -target 8
-Djava.ext.dirs=GooZip${PS}BadJar
-classpath BadZip/Lib.zip
Main.java""");
//----------------------------------------------------------------
expectFail(JAVAC, "-classpath BadClass${PS}GooClass Main.java");
expectPass(JAVAC, "-classpath GooClass${PS}BadClass Main.java");
expectFail(JAVA, "-classpath BadClass${PS}GooClass${PS}. Main");
expectPass(JAVA, "-classpath GooClass${PS}BadClass${PS}. Main");
expectFail(JAVAC, "-cp BadJar/Lib.jar${PS}GooZip/Lib.zip Main.java");
expectPass(JAVAC, "-cp GooJar/Lib.jar${PS}BadZip/Lib.zip Main.java");
expectFail(JAVA, "-cp BadJar/Lib.jar${PS}${PS}GooZip/Lib.zip Main");
expectPass(JAVA, "-cp GooJar/Lib.jar${PS}${PS}BadZip/Lib.zip Main");
//----------------------------------------------------------------
expectFail(classpath("BadZip/Lib.zip${PS}GooJar/Lib.jar"), JAVAC,"Main.java");
expectPass(classpath("GooZip/Lib.zip${PS}BadJar/Lib.jar"), JAVAC, "Main.java");
expectFail(classpath("${PS}BadZip/Lib.zip${PS}GooJar/Lib.jar"), JAVA, "Main");
expectPass(classpath("${PS}GooZip/Lib.zip${PS}BadJar/Lib.jar"), JAVA, "Main");
//----------------------------------------------------------------
// Check behavior of empty paths and empty path elements
//----------------------------------------------------------------
Path GooClass = Path.of("GooClass");
Path GooJar = Path.of("GooJar");
expectFail(GooClass, JAVAC, "-cp .. ../Main.java");
expectFail(GooClass, JAVA, "-cp .. Main");
// Unspecified classpath defaults to "."
Path OneDir = Path.of("OneDir");
tb.createDirectories(OneDir);
tb.copyFile(Path.of("Main.java"), OneDir);
tb.copyFile(GooClass.resolve("Lib.class"), OneDir);
expectPass(OneDir, JAVAC, "Main.java");
expectPass(OneDir, JAVA, "Main");
// Empty classpath elements mean "."
expectPass(GooClass, JAVAC, "-cp ${PS}.. ../Main.java");
expectPass(GooClass, JAVA, "-cp ${PS}.. Main");
expectPass(GooClass, JAVAC, "-cp ..${PS} ../Main.java");
expectPass(GooClass, JAVA, "-cp ..${PS} Main");
expectPass(GooClass, JAVAC, "-cp ..${PS}${PS}/xyzzy ../Main.java");
expectPass(GooClass, JAVA, "-cp ..${PS}${PS}/xyzzy Main");
// All other empty path elements are ignored.
// note presence of empty arg in this invocation
expectFail(GooJar, null, JAVAC, "-source", "8", "-target", "8", "-extdirs", "", "-cp", "..", "../Main.java");
expectFail(GooJar, JAVAC, "-source 8 -target 8 -extdirs ${PS} -cp .. ../Main.java");
expectFail(GooJar, JAVAC, "-source 8 -target 8 -Djava.ext.dirs=${PS} -cp .. ../Main.java");
expectPass(GooJar, JAVAC, "-source 8 -target 8 -extdirs . -cp .. ../Main.java");
expectPass(GooJar, JAVAC, "-source 8 -target 8 -Djava.ext.dirs=. -cp .. ../Main.java");
expectFail(GooJar, JAVAC, "-source 8 -target 8 -Djava.endorsed.dirs= -cp .. ../Main.java");
expectFail(GooJar, JAVAC, "-source 8 -target 8 -endorseddirs ${PS} -cp .. ../Main.java");
expectPass(GooJar, JAVAC, "-source 8 -target 8 -Djava.endorsed.dirs=. -cp .. ../Main.java");
expectFail(GooClass, JAVAC, "-source 8 -target 8 -Xbootclasspath/p: -cp .. ../Main.java");
expectPass(GooClass, JAVAC, "-source 8 -target 8 -Xbootclasspath/p:. -cp .. ../Main.java");
expectFail(GooClass, JAVAC, "-source 8 -target 8 -Xbootclasspath:../java-lang.jar -cp .. ../Main.java");
expectPass(GooClass, JAVAC, "-source 8 -target 8 -Xbootclasspath:../java-lang.jar${PS}. -cp .. ../Main.java");
expectFail(GooClass, JAVAC, "-source 8 -target 8 -Xbootclasspath/a: -cp .. ../Main.java");
expectFail(GooClass, JAVA, "-Xbootclasspath/a: -cp .. Main");
expectPass(GooClass, JAVAC, "-source 8 -target 8 -Xbootclasspath/a:. -cp .. ../Main.java");
expectPass(GooClass, JAVA, "-Xbootclasspath/a:. -cp .. Main");
}
}