diff --git a/test/lib-test/jdk/test/lib/process/proc/A.java b/test/lib-test/jdk/test/lib/process/proc/A.java new file mode 100644 index 00000000000..8f80202b697 --- /dev/null +++ b/test/lib-test/jdk/test/lib/process/proc/A.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023, 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. + */ +public class A { + public static void main(String[] args) throws Exception { + B.go(); + } +} diff --git a/test/lib-test/jdk/test/lib/process/proc/B.java b/test/lib-test/jdk/test/lib/process/proc/B.java new file mode 100644 index 00000000000..ef92b3f77a2 --- /dev/null +++ b/test/lib-test/jdk/test/lib/process/proc/B.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023, 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. + */ +public class B { + public static void go() { + System.out.println("Hello"); + System.err.println("World"); + } +} diff --git a/test/lib-test/jdk/test/lib/process/proc/Launcher.java b/test/lib-test/jdk/test/lib/process/proc/Launcher.java new file mode 100644 index 00000000000..857586586c6 --- /dev/null +++ b/test/lib-test/jdk/test/lib/process/proc/Launcher.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023, 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. + */ +import jdk.test.lib.process.Proc; + +/* + * @test + * @bug 8305846 + * @library /test/lib + */ +public class Launcher { + public static void main(String[] args) throws Exception { + Proc.create("A") + .compile() + .start() + .output() + .stdoutShouldContain("Hello") + .stderrShouldContain("World"); + } +} diff --git a/test/lib/jdk/test/lib/process/Proc.java b/test/lib/jdk/test/lib/process/Proc.java index 574e5761d03..0c294e465ab 100644 --- a/test/lib/jdk/test/lib/process/Proc.java +++ b/test/lib/jdk/test/lib/process/Proc.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, 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 @@ -23,6 +23,8 @@ package jdk.test.lib.process; +import jdk.test.lib.compiler.CompilerUtils; + import java.io.BufferedReader; import java.io.File; import java.io.IOException; @@ -118,7 +120,11 @@ public class Proc { private boolean inheritIO = false; private boolean noDump = false; - private List cp; // user-provided classpath + private boolean addcp; // user-provided classpath is appended + private List cp; // user-provided classpaths + + private boolean compile; // compile the program as well + private String clazz; // Class to launch private String debug; // debug flag, controller will show data // transfer between procs. If debug is set, @@ -195,8 +201,7 @@ public class Proc { } return this; } - // Sets classpath. If not called, Proc will choose a classpath. If called - // with no arg, no classpath will be used. Can be called multiple times. + // Sets classpath. Can be called multiple times. public Proc cp(String... s) { if (cp == null) { cp = new ArrayList<>(); @@ -204,6 +209,12 @@ public class Proc { cp.addAll(Arrays.asList(s)); return this; } + // Adds classpath to defaults. Can be called multiple times. + // Once called, addcp is always true. + public Proc addcp(String... s) { + addcp = true; + return cp(s); + } // Adds a permission to policy. Can be called multiple times. // All perm() calls after a series of grant() calls are grouped into // a single grant block. perm() calls before any grant() call are grouped @@ -259,6 +270,34 @@ public class Proc { grant.append(v).append(", "); return this; } + // Compile as well + public Proc compile() { + compile = true; + return this; + } + + // get full classpath. + // 1. Default classpath used if neither cp() or addcp() is called + // 2. User provided classpath (can be empty) used if only cp() is called + // 3. User provided classpath + default classpath used, otherwise + String fullcp() { + if (cp == null) { + return System.getProperty("test.class.path") + File.pathSeparator + + System.getProperty("test.src.path"); + } else { + var newcp = new ArrayList<>(cp); + if (addcp) { + newcp.add(System.getProperty("test.class.path")); + newcp.add(System.getProperty("test.src.path")); + } + if (!newcp.isEmpty()) { + return newcp.stream().collect(Collectors.joining(File.pathSeparator)); + } else { + return null; + } + } + } + // Starts the proc public Proc start() throws IOException { List cmd = new ArrayList<>(); @@ -282,18 +321,26 @@ public class Proc { } } + var lcp = fullcp(); + if (lcp != null) { + cmd.add("-cp"); + cmd.add(lcp); + } + + if (compile) { + boolean comp = CompilerUtils.compile( + Path.of(System.getProperty("test.src"), clazz + ".java"), + Path.of(System.getProperty("test.classes")), + cmd.subList(1, cmd.size()).toArray(new String[0])); + // subList(1): all options added without launcher name + if (!comp) { + throw new RuntimeException("Compilation error"); + } + } + Collections.addAll(cmd, splitProperty("test.vm.opts")); Collections.addAll(cmd, splitProperty("test.java.opts")); - if (cp == null) { - cmd.add("-cp"); - cmd.add(System.getProperty("test.class.path") + File.pathSeparator + - System.getProperty("test.src.path")); - } else if (!cp.isEmpty()) { - cmd.add("-cp"); - cmd.add(cp.stream().collect(Collectors.joining(File.pathSeparator))); - } - if (!secprop.isEmpty()) { Path p = Path.of(getId("security")); try (OutputStream fos = Files.newOutputStream(p);