author | weijun |
Mon, 22 Apr 2019 13:01:57 +0800 | |
changeset 58612 | 32aff2b7585b |
parent 49682 | 2918e1146106 |
permissions | -rw-r--r-- |
18536 | 1 |
/* |
58612 | 2 |
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. |
18536 | 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.BufferedReader; |
|
25 |
import java.io.File; |
|
26 |
import java.io.IOException; |
|
27 |
import java.io.InputStreamReader; |
|
58612 | 28 |
import java.io.OutputStream; |
29 |
import java.io.PrintStream; |
|
30 |
import java.io.UncheckedIOException; |
|
18536 | 31 |
import java.nio.file.Files; |
32 |
import java.nio.file.Path; |
|
33 |
import java.nio.file.Paths; |
|
34 |
import java.security.Permission; |
|
41377
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
35 |
import java.security.Principal; |
18536 | 36 |
import java.util.ArrayList; |
40261
86a49ba76f52
8136930: Simplify use of module-system options by custom launchers
mchung
parents:
36511
diff
changeset
|
37 |
import java.util.Arrays; |
18536 | 38 |
import java.util.Base64; |
36511 | 39 |
import java.util.Collections; |
18536 | 40 |
import java.util.HashMap; |
41 |
import java.util.List; |
|
42 |
import java.util.Map; |
|
43 |
import java.util.Map.Entry; |
|
41377
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
44 |
import java.util.stream.Collectors; |
40261
86a49ba76f52
8136930: Simplify use of module-system options by custom launchers
mchung
parents:
36511
diff
changeset
|
45 |
import java.util.stream.Stream; |
18536 | 46 |
|
47 |
/** |
|
48 |
* This is a test library that makes writing a Java test that spawns multiple |
|
49 |
* Java processes easily. |
|
50 |
* |
|
51 |
* Usage: |
|
52 |
* |
|
53 |
* Proc.create("Clazz") // The class to launch |
|
54 |
* .args("x") // with args |
|
55 |
* .env("env", "value") // and an environment variable |
|
56 |
* .prop("key","value") // and a system property |
|
41377
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
57 |
* .grant(file) // grant codes in this codebase |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
58 |
* .perm(perm) // with the permission |
18536 | 59 |
* .start(); // and start |
60 |
* |
|
61 |
* create/start must be called, args/env/prop/perm can be called zero or |
|
62 |
* multiple times between create and start. |
|
63 |
* |
|
64 |
* The controller can call inheritIO to share its I/O to the process. |
|
65 |
* Otherwise, it can send data into a proc's stdin with write/println, and |
|
41377
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
66 |
* read its stdout with readLine. stderr is always redirected to a file |
18536 | 67 |
* unless nodump() is called. A protocol is designed to make |
68 |
* data exchange among the controller and the processes super easy, in which |
|
69 |
* useful data are always printed with a special prefix ("PROCISFUN:"). |
|
70 |
* If the data is binary, make it BASE64. |
|
71 |
* |
|
72 |
* For example: |
|
73 |
* |
|
74 |
* - A producer Proc calls Proc.binOut() or Proc.textOut() to send out data. |
|
75 |
* This method would prints to the stdout something like |
|
76 |
* |
|
77 |
* PROCISFUN:[raw text or base64 binary] |
|
78 |
* |
|
79 |
* - The controller calls producer.readData() to get the content. This method |
|
80 |
* ignores all other output and only reads lines starting with "PROCISFUN:". |
|
81 |
* |
|
82 |
* - The controller does not care if the context is text or base64, it simply |
|
83 |
* feeds the data to a consumer Proc by calling consumer.println(data). |
|
84 |
* This will be printed into System.in of the consumer process. |
|
85 |
* |
|
86 |
* - The consumer Proc calls Proc.binIn() or Proc.textIn() to read the data. |
|
87 |
* The first method de-base64 the input and return a byte[] block. |
|
88 |
* |
|
89 |
* Please note only plain ASCII is supported in raw text at the moment. |
|
90 |
* |
|
91 |
* As the Proc objects are hidden so deeply, two static methods, d(String) and |
|
92 |
* d(Throwable) are provided to output info into stderr, where they will |
|
41377
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
93 |
* normally be appended messages to a debug file (unless nodump() is called). |
18536 | 94 |
* Developers can view the messages in real time by calling |
95 |
* |
|
41377
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
96 |
* {@code tail -f stderr.<debug>} |
18536 | 97 |
* |
98 |
* TODO: |
|
99 |
* |
|
100 |
* . launch java tools, say, keytool |
|
101 |
* . launch another version of java |
|
102 |
* . start in another directory |
|
103 |
* . start and finish using one method |
|
104 |
* |
|
105 |
* This is not a test, but is the core of |
|
106 |
* JDK-8009977: A test library to launch multiple Java processes |
|
107 |
*/ |
|
108 |
public class Proc { |
|
109 |
private Process p; |
|
110 |
private BufferedReader br; // the stdout of a process |
|
111 |
private String launcher; // Optional: the java program |
|
112 |
||
113 |
private List<String> args = new ArrayList<>(); |
|
114 |
private Map<String,String> env = new HashMap<>(); |
|
115 |
private Map<String,String> prop = new HashMap(); |
|
58612 | 116 |
private Map<String,String> secprop = new HashMap(); |
18536 | 117 |
private boolean inheritIO = false; |
118 |
private boolean noDump = false; |
|
119 |
||
41377
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
120 |
private List<String> cp; // user-provided classpath |
18536 | 121 |
private String clazz; // Class to launch |
122 |
private String debug; // debug flag, controller will show data |
|
41377
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
123 |
// transfer between procs. If debug is set, |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
124 |
// it MUST be different between Procs. |
18536 | 125 |
|
126 |
final private static String PREFIX = "PROCISFUN:"; |
|
41377
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
127 |
|
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
128 |
// policy file |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
129 |
final private StringBuilder perms = new StringBuilder(); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
130 |
// temporary saving the grant line in a policy file |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
131 |
final private StringBuilder grant = new StringBuilder(); |
18536 | 132 |
|
133 |
// The following methods are called by controllers |
|
134 |
||
135 |
// Creates a Proc by the Java class name, launcher is an optional |
|
136 |
// argument to specify the java program |
|
137 |
public static Proc create(String clazz, String... launcher) { |
|
138 |
Proc pc = new Proc(); |
|
139 |
pc.clazz = clazz; |
|
140 |
if (launcher.length > 0) { |
|
141 |
pc.launcher = launcher[0]; |
|
142 |
} |
|
143 |
return pc; |
|
144 |
} |
|
145 |
// Sets inheritIO flag to proc. If set, proc will same I/O channels as |
|
146 |
// teh controller. Otherwise, its stdin/stdout is untouched, and its |
|
147 |
// stderr is redirected to DFILE. |
|
148 |
public Proc inheritIO() { |
|
149 |
inheritIO = true; |
|
150 |
return this; |
|
151 |
} |
|
152 |
// When called, stderr inherits parent stderr, otherwise, append to a file |
|
153 |
public Proc nodump() { |
|
154 |
noDump = true; |
|
155 |
return this; |
|
156 |
} |
|
157 |
// Specifies some args. Can be called multiple times. |
|
158 |
public Proc args(String... args) { |
|
159 |
for (String c: args) { |
|
160 |
this.args.add(c); |
|
161 |
} |
|
162 |
return this; |
|
163 |
} |
|
164 |
// Returns debug prefix |
|
165 |
public String debug() { |
|
166 |
return debug; |
|
167 |
} |
|
168 |
// Enables debug with prefix |
|
169 |
public Proc debug(String title) { |
|
170 |
debug = title; |
|
171 |
return this; |
|
172 |
} |
|
173 |
// Specifies an env var. Can be called multiple times. |
|
174 |
public Proc env(String a, String b) { |
|
175 |
env.put(a, b); |
|
176 |
return this; |
|
177 |
} |
|
178 |
// Specifies a Java system property. Can be called multiple times. |
|
179 |
public Proc prop(String a, String b) { |
|
180 |
prop.put(a, b); |
|
181 |
return this; |
|
182 |
} |
|
58612 | 183 |
// Specifies a security property. Can be called multiple times. |
184 |
public Proc secprop(String a, String b) { |
|
185 |
secprop.put(a, b); |
|
186 |
return this; |
|
187 |
} |
|
43803
e1881d258206
8168410: Multiple JCK tests are failing due to SecurityException is not thrown.
weijun
parents:
42338
diff
changeset
|
188 |
// Inherit the value of a system property |
e1881d258206
8168410: Multiple JCK tests are failing due to SecurityException is not thrown.
weijun
parents:
42338
diff
changeset
|
189 |
public Proc inheritProp(String k) { |
e1881d258206
8168410: Multiple JCK tests are failing due to SecurityException is not thrown.
weijun
parents:
42338
diff
changeset
|
190 |
String v = System.getProperty(k); |
e1881d258206
8168410: Multiple JCK tests are failing due to SecurityException is not thrown.
weijun
parents:
42338
diff
changeset
|
191 |
if (v != null) { |
e1881d258206
8168410: Multiple JCK tests are failing due to SecurityException is not thrown.
weijun
parents:
42338
diff
changeset
|
192 |
prop.put(k, v); |
e1881d258206
8168410: Multiple JCK tests are failing due to SecurityException is not thrown.
weijun
parents:
42338
diff
changeset
|
193 |
} |
e1881d258206
8168410: Multiple JCK tests are failing due to SecurityException is not thrown.
weijun
parents:
42338
diff
changeset
|
194 |
return this; |
e1881d258206
8168410: Multiple JCK tests are failing due to SecurityException is not thrown.
weijun
parents:
42338
diff
changeset
|
195 |
} |
41377
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
196 |
// Sets classpath. If not called, Proc will choose a classpath. If called |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
197 |
// with no arg, no classpath will be used. Can be called multiple times. |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
198 |
public Proc cp(String... s) { |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
199 |
if (cp == null) { |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
200 |
cp = new ArrayList<>(); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
201 |
} |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
202 |
cp.addAll(Arrays.asList(s)); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
203 |
return this; |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
204 |
} |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
205 |
// Adds a permission to policy. Can be called multiple times. |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
206 |
// All perm() calls after a series of grant() calls are grouped into |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
207 |
// a single grant block. perm() calls before any grant() call are grouped |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
208 |
// into a grant block with no restriction. |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
209 |
// Please note that in order to make permissions effective, also call |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
210 |
// prop("java.security.manager", ""). |
18536 | 211 |
public Proc perm(Permission p) { |
41377
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
212 |
if (grant.length() != 0) { // Right after grant(s) |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
213 |
if (perms.length() != 0) { // Not first block |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
214 |
perms.append("};\n"); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
215 |
} |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
216 |
perms.append("grant ").append(grant).append(" {\n"); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
217 |
grant.setLength(0); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
218 |
} else { |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
219 |
if (perms.length() == 0) { // First block w/o restriction |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
220 |
perms.append("grant {\n"); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
221 |
} |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
222 |
} |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
223 |
if (p.getActions().isEmpty()) { |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
224 |
String s = String.format("%s \"%s\"", |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
225 |
p.getClass().getCanonicalName(), |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
226 |
p.getName() |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
227 |
.replace("\\", "\\\\").replace("\"", "\\\"")); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
228 |
perms.append(" permission ").append(s).append(";\n"); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
229 |
} else { |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
230 |
String s = String.format("%s \"%s\", \"%s\"", |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
231 |
p.getClass().getCanonicalName(), |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
232 |
p.getName() |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
233 |
.replace("\\", "\\\\").replace("\"", "\\\""), |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
234 |
p.getActions()); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
235 |
perms.append(" permission ").append(s).append(";\n"); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
236 |
} |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
237 |
return this; |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
238 |
} |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
239 |
|
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
240 |
// Adds a grant option to policy. If called in a row, a single grant block |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
241 |
// with all options will be created. If there are perm() call(s) between |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
242 |
// grant() calls, they belong to different grant blocks |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
243 |
|
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
244 |
// grant on a principal |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
245 |
public Proc grant(Principal p) { |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
246 |
grant.append("principal ").append(p.getClass().getName()) |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
247 |
.append(" \"").append(p.getName()).append("\", "); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
248 |
return this; |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
249 |
} |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
250 |
// grant on a codebase |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
251 |
public Proc grant(File f) { |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
252 |
grant.append("codebase \"").append(f.toURI()).append("\", "); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
253 |
return this; |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
254 |
} |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
255 |
// arbitrary grant |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
256 |
public Proc grant(String v) { |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
257 |
grant.append(v).append(", "); |
18536 | 258 |
return this; |
259 |
} |
|
260 |
// Starts the proc |
|
261 |
public Proc start() throws IOException { |
|
262 |
List<String> cmd = new ArrayList<>(); |
|
41832 | 263 |
boolean hasModules; |
18536 | 264 |
if (launcher != null) { |
265 |
cmd.add(launcher); |
|
41832 | 266 |
File base = new File(launcher).getParentFile().getParentFile(); |
267 |
hasModules = new File(base, "modules").exists() || |
|
268 |
new File(base, "jmods").exists(); |
|
18536 | 269 |
} else { |
270 |
cmd.add(new File(new File(System.getProperty("java.home"), "bin"), |
|
271 |
"java").getPath()); |
|
41832 | 272 |
hasModules = true; |
18536 | 273 |
} |
36511 | 274 |
|
41832 | 275 |
if (hasModules) { |
276 |
Stream.of(jdk.internal.misc.VM.getRuntimeArguments()) |
|
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41832
diff
changeset
|
277 |
.filter(arg -> arg.startsWith("--add-exports=") || |
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41832
diff
changeset
|
278 |
arg.startsWith("--add-opens=")) |
41832 | 279 |
.forEach(cmd::add); |
280 |
} |
|
36511 | 281 |
|
282 |
Collections.addAll(cmd, splitProperty("test.vm.opts")); |
|
283 |
Collections.addAll(cmd, splitProperty("test.java.opts")); |
|
284 |
||
41377
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
285 |
if (cp == null) { |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
286 |
cmd.add("-cp"); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
287 |
cmd.add(System.getProperty("test.class.path") + File.pathSeparator + |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
288 |
System.getProperty("test.src.path")); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
289 |
} else if (!cp.isEmpty()) { |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
290 |
cmd.add("-cp"); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
291 |
cmd.add(cp.stream().collect(Collectors.joining(File.pathSeparator))); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
292 |
} |
36511 | 293 |
|
58612 | 294 |
if (!secprop.isEmpty()) { |
295 |
Path p = Path.of(getId("security")); |
|
296 |
try (OutputStream fos = Files.newOutputStream(p); |
|
297 |
PrintStream ps = new PrintStream(fos)) { |
|
298 |
secprop.forEach((k,v) -> ps.println(k + "=" + v)); |
|
299 |
} catch (IOException e) { |
|
300 |
throw new UncheckedIOException(e); |
|
301 |
} |
|
302 |
prop.put("java.security.properties", p.toString()); |
|
303 |
} |
|
304 |
||
18536 | 305 |
for (Entry<String,String> e: prop.entrySet()) { |
306 |
cmd.add("-D" + e.getKey() + "=" + e.getValue()); |
|
307 |
} |
|
41377
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
308 |
if (perms.length() > 0) { |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
309 |
Path p = Paths.get(getId("policy")).toAbsolutePath(); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
310 |
perms.append("};\n"); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
311 |
Files.write(p, perms.toString().getBytes()); |
18536 | 312 |
cmd.add("-Djava.security.policy=" + p.toString()); |
313 |
} |
|
314 |
cmd.add(clazz); |
|
315 |
for (String s: args) { |
|
316 |
cmd.add(s); |
|
317 |
} |
|
318 |
if (debug != null) { |
|
319 |
System.out.println("PROC: " + debug + " cmdline: " + cmd); |
|
49682
2918e1146106
8200468: Port the native GSS-API bridge to Windows
weijun
parents:
47227
diff
changeset
|
320 |
for (String e : env.keySet()) { |
2918e1146106
8200468: Port the native GSS-API bridge to Windows
weijun
parents:
47227
diff
changeset
|
321 |
System.out.print(e + "=" + env.get(e) + " "); |
2918e1146106
8200468: Port the native GSS-API bridge to Windows
weijun
parents:
47227
diff
changeset
|
322 |
} |
41377
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
323 |
for (String c : cmd) { |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
324 |
if (c.indexOf('\\') >= 0 || c.indexOf(' ') > 0) { |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
325 |
System.out.print('\'' + c + '\''); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
326 |
} else { |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
327 |
System.out.print(c); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
328 |
} |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
329 |
System.out.print(' '); |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
330 |
} |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
331 |
System.out.println(); |
18536 | 332 |
} |
333 |
ProcessBuilder pb = new ProcessBuilder(cmd); |
|
334 |
for (Entry<String,String> e: env.entrySet()) { |
|
335 |
pb.environment().put(e.getKey(), e.getValue()); |
|
336 |
} |
|
337 |
if (inheritIO) { |
|
338 |
pb.inheritIO(); |
|
339 |
} else if (noDump) { |
|
340 |
pb.redirectError(ProcessBuilder.Redirect.INHERIT); |
|
341 |
} else { |
|
41377
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
342 |
pb.redirectError(ProcessBuilder.Redirect |
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
343 |
.appendTo(new File(getId("stderr")))); |
18536 | 344 |
} |
345 |
p = pb.start(); |
|
346 |
br = new BufferedReader(new InputStreamReader(p.getInputStream())); |
|
347 |
return this; |
|
348 |
} |
|
47227
8052fa06e1b7
8186884: Test native KDC, Java krb5 lib, and native krb5 lib in one test
weijun
parents:
47216
diff
changeset
|
349 |
String getId(String suffix) { |
8052fa06e1b7
8186884: Test native KDC, Java krb5 lib, and native krb5 lib in one test
weijun
parents:
47216
diff
changeset
|
350 |
if (debug != null) { |
8052fa06e1b7
8186884: Test native KDC, Java krb5 lib, and native krb5 lib in one test
weijun
parents:
47216
diff
changeset
|
351 |
return debug + "." + suffix; |
8052fa06e1b7
8186884: Test native KDC, Java krb5 lib, and native krb5 lib in one test
weijun
parents:
47216
diff
changeset
|
352 |
} else { |
8052fa06e1b7
8186884: Test native KDC, Java krb5 lib, and native krb5 lib in one test
weijun
parents:
47216
diff
changeset
|
353 |
return System.identityHashCode(this) + "." + suffix; |
8052fa06e1b7
8186884: Test native KDC, Java krb5 lib, and native krb5 lib in one test
weijun
parents:
47216
diff
changeset
|
354 |
} |
41377
271ee055cb31
8164705: Remove pathname canonicalization from FilePermission
weijun
parents:
40261
diff
changeset
|
355 |
} |
18536 | 356 |
// Reads a line from stdout of proc |
357 |
public String readLine() throws IOException { |
|
358 |
String s = br.readLine(); |
|
359 |
if (debug != null) { |
|
360 |
System.out.println("PROC: " + debug + " readline: " + |
|
361 |
(s == null ? "<EOF>" : s)); |
|
362 |
} |
|
363 |
return s; |
|
364 |
} |
|
365 |
// Reads a special line from stdout of proc |
|
366 |
public String readData() throws Exception { |
|
367 |
while (true) { |
|
368 |
String s = readLine(); |
|
369 |
if (s == null) { |
|
370 |
if (p.waitFor() != 0) { |
|
371 |
throw new Exception("Proc abnormal end"); |
|
372 |
} else { |
|
373 |
return s; |
|
374 |
} |
|
375 |
} |
|
376 |
if (s.startsWith(PREFIX)) { |
|
377 |
return s.substring(PREFIX.length()); |
|
378 |
} |
|
379 |
} |
|
380 |
} |
|
381 |
// Writes text into stdin of proc |
|
382 |
public void println(String s) throws IOException { |
|
383 |
if (debug != null) { |
|
384 |
System.out.println("PROC: " + debug + " println: " + s); |
|
385 |
} |
|
386 |
write((s + "\n").getBytes()); |
|
387 |
} |
|
388 |
// Writes data into stdin of proc |
|
389 |
public void write(byte[] b) throws IOException { |
|
390 |
p.getOutputStream().write(b); |
|
391 |
p.getOutputStream().flush(); |
|
392 |
} |
|
393 |
// Reads all output and wait for process end |
|
394 |
public int waitFor() throws Exception { |
|
395 |
while (true) { |
|
396 |
String s = readLine(); |
|
397 |
if (s == null) { |
|
398 |
break; |
|
399 |
} |
|
400 |
} |
|
401 |
return p.waitFor(); |
|
402 |
} |
|
58612 | 403 |
// Wait for process end with expected exit code |
404 |
public void waitFor(int expected) throws Exception { |
|
405 |
if (p.waitFor() != expected) { |
|
406 |
throw new RuntimeException("Exit code not " + expected); |
|
407 |
} |
|
408 |
} |
|
18536 | 409 |
|
410 |
// The following methods are used inside a proc |
|
411 |
||
412 |
// Writes out a BASE64 binary with a prefix |
|
413 |
public static void binOut(byte[] data) { |
|
414 |
System.out.println(PREFIX + Base64.getEncoder().encodeToString(data)); |
|
415 |
} |
|
416 |
// Reads in a line of BASE64 binary |
|
417 |
public static byte[] binIn() throws Exception { |
|
418 |
return Base64.getDecoder().decode(textIn()); |
|
419 |
} |
|
420 |
// Writes out a text with a prefix |
|
421 |
public static void textOut(String data) { |
|
422 |
System.out.println(PREFIX + data); |
|
423 |
} |
|
424 |
// Reads in a line of text |
|
425 |
public static String textIn() throws Exception { |
|
426 |
StringBuilder sb = new StringBuilder(); |
|
427 |
boolean isEmpty = true; |
|
428 |
while (true) { |
|
429 |
int i = System.in.read(); |
|
47227
8052fa06e1b7
8186884: Test native KDC, Java krb5 lib, and native krb5 lib in one test
weijun
parents:
47216
diff
changeset
|
430 |
if (i == -1) { |
8052fa06e1b7
8186884: Test native KDC, Java krb5 lib, and native krb5 lib in one test
weijun
parents:
47216
diff
changeset
|
431 |
break; |
8052fa06e1b7
8186884: Test native KDC, Java krb5 lib, and native krb5 lib in one test
weijun
parents:
47216
diff
changeset
|
432 |
} |
18536 | 433 |
isEmpty = false; |
47227
8052fa06e1b7
8186884: Test native KDC, Java krb5 lib, and native krb5 lib in one test
weijun
parents:
47216
diff
changeset
|
434 |
if (i == '\n') { |
8052fa06e1b7
8186884: Test native KDC, Java krb5 lib, and native krb5 lib in one test
weijun
parents:
47216
diff
changeset
|
435 |
break; |
8052fa06e1b7
8186884: Test native KDC, Java krb5 lib, and native krb5 lib in one test
weijun
parents:
47216
diff
changeset
|
436 |
} |
18536 | 437 |
if (i != 13) { |
438 |
// Force it to a char, so only simple ASCII works. |
|
439 |
sb.append((char)i); |
|
440 |
} |
|
441 |
} |
|
442 |
return isEmpty ? null : sb.toString(); |
|
443 |
} |
|
444 |
// Sends string to stderr. If inheritIO is not called, they will |
|
445 |
// be collected into DFILE |
|
446 |
public static void d(String s) throws IOException { |
|
447 |
System.err.println(s); |
|
448 |
} |
|
449 |
// Sends an exception to stderr |
|
450 |
public static void d(Throwable e) throws IOException { |
|
451 |
e.printStackTrace(); |
|
452 |
} |
|
36511 | 453 |
|
454 |
private static String[] splitProperty(String prop) { |
|
455 |
String s = System.getProperty(prop); |
|
456 |
if (s == null || s.trim().isEmpty()) { |
|
457 |
return new String[] {}; |
|
458 |
} |
|
459 |
return s.trim().split("\\s+"); |
|
460 |
} |
|
18536 | 461 |
} |