Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/sun/tools/jcmd/TestProcessHelper.java
41149 views
1
/*
2
* Copyright (c) 2019, 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.File;
25
import java.io.IOException;
26
import java.io.OutputStream;
27
import java.lang.invoke.MethodHandle;
28
import java.lang.invoke.MethodHandles;
29
import java.lang.module.ModuleDescriptor;
30
import java.lang.reflect.Method;
31
import java.nio.file.FileSystems;
32
import java.nio.file.Files;
33
import java.nio.file.Path;
34
import java.util.ArrayList;
35
import java.util.LinkedList;
36
import java.util.List;
37
import java.util.jar.Attributes;
38
import java.util.jar.JarEntry;
39
import java.util.jar.JarOutputStream;
40
import java.util.jar.Manifest;
41
import java.util.stream.Collectors;
42
import java.util.stream.Stream;
43
44
import jdk.internal.module.ModuleInfoWriter;
45
import jdk.test.lib.JDKToolFinder;
46
import jdk.test.lib.process.ProcessTools;
47
import jdk.test.lib.util.JarUtils;
48
49
/*
50
* @test
51
* @bug 8205654
52
* @summary Unit test for sun.tools.ProcessHelper class. The test launches Java processes with different Java options
53
* and checks that sun.tools.ProcessHelper.getMainClass(pid) method returns a correct main class. return a .
54
*
55
* @requires os.family == "linux"
56
* @library /test/lib
57
* @modules jdk.jcmd/sun.tools.common:+open
58
* java.base/jdk.internal.module
59
* @build test.TestProcess
60
* @run main/othervm TestProcessHelper
61
*/
62
public class TestProcessHelper {
63
64
private static final String TEST_PROCESS_MAIN_CLASS_NAME = "TestProcess";
65
private static final String TEST_PROCESS_MAIN_CLASS_PACKAGE = "test";
66
private static final String TEST_PROCESS_MAIN_CLASS = TEST_PROCESS_MAIN_CLASS_PACKAGE + "."
67
+ TEST_PROCESS_MAIN_CLASS_NAME;
68
private static final Path TEST_CLASSES = FileSystems.getDefault().getPath(System.getProperty("test.classes"));
69
private static final Path USER_DIR = FileSystems.getDefault().getPath(System.getProperty("user.dir", "."));
70
private static final Path TEST_MODULES = USER_DIR.resolve("testmodules");
71
private static final String JAVA_PATH = JDKToolFinder.getJDKTool("java");
72
private static final Path TEST_CLASS = TEST_CLASSES.resolve(TEST_PROCESS_MAIN_CLASS_PACKAGE)
73
.resolve(TEST_PROCESS_MAIN_CLASS_NAME + ".class");
74
75
private static final String[] CP_OPTIONS = {"-cp", "-classpath", "--class-path"};
76
private static final String[][] VM_ARGS = {{}, {"-Dtest1=aaa"}, {"-Dtest1=aaa", "-Dtest2=bbb ccc"}};
77
private static final String[][] ARGS = {{}, {"param1"}, {"param1", "param2"}};
78
private static final String[] MP_OPTIONS = {"-p", "--module-path"};
79
private static final String[] MODULE_OPTIONS = {"-m", "--module", "--module="};
80
private static final String JAR_OPTION = "-jar";
81
private static final String MODULE_NAME = "module1";
82
private static final String[][] EXTRA_MODULAR_OPTIONS = {null,
83
{"--add-opens", "java.base/java.net=ALL-UNNAMED"},
84
{"--add-exports", "java.base/java.net=ALL-UNNAMED"},
85
{"--add-reads", "java.base/java.net=ALL-UNNAMED"},
86
{"--add-modules", "java.management"},
87
{"--limit-modules", "java.management"},
88
{"--upgrade-module-path", "test"}};
89
90
private static final String[] PATCH_MODULE_OPTIONS = {"--patch-module", null};
91
92
private static final MethodHandle MH_GET_MAIN_CLASS = resolveMainClassMH();
93
94
private static MethodHandle resolveMainClassMH() {
95
try {
96
Method getMainClassMethod = Class
97
.forName("sun.tools.common.ProcessHelper")
98
.getDeclaredMethod("getMainClass", String.class);
99
getMainClassMethod.setAccessible(true);
100
return MethodHandles.lookup().unreflect(getMainClassMethod);
101
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException e) {
102
throw new RuntimeException(e);
103
}
104
}
105
106
private static String callGetMainClass(Process p) {
107
try {
108
return (String)MH_GET_MAIN_CLASS.invoke(Long.toString(p.pid()));
109
} catch (Throwable e) {
110
throw new RuntimeException(e);
111
}
112
113
}
114
115
public static void main(String[] args) throws Exception {
116
new TestProcessHelper().runTests();
117
}
118
119
public void runTests() throws Exception {
120
testClassPath();
121
testJar();
122
testModule();
123
}
124
125
// Test Java processes that are started with -classpath, -cp, or --class-path options
126
// and with different combinations of VM and program args.
127
private void testClassPath() throws Exception {
128
for (String cp : CP_OPTIONS) {
129
for (String[] vma : VM_ARGS) {
130
for (String[] arg : ARGS) {
131
for (String[] modularOptions : EXTRA_MODULAR_OPTIONS) {
132
List<String> cmd = new LinkedList<>();
133
cmd.add(JAVA_PATH);
134
cmd.add(cp);
135
cmd.add(TEST_CLASSES.toAbsolutePath().toString());
136
for (String v : vma) {
137
cmd.add(v);
138
}
139
if (modularOptions != null) {
140
cmd.add(modularOptions[0]);
141
cmd.add(modularOptions[1]);
142
}
143
cmd.add(TEST_PROCESS_MAIN_CLASS);
144
for (String a : arg) {
145
cmd.add(a);
146
}
147
testProcessHelper(cmd, TEST_PROCESS_MAIN_CLASS);
148
}
149
}
150
}
151
}
152
}
153
154
// Test Java processes that are started with -jar option
155
// and with different combinations of VM and program args.
156
private void testJar() throws Exception {
157
File jarFile = prepareJar();
158
for (String[] vma : VM_ARGS) {
159
for (String[] arg : ARGS) {
160
List<String> cmd = new LinkedList<>();
161
cmd.add(JAVA_PATH);
162
for (String v : vma) {
163
cmd.add(v);
164
}
165
cmd.add(JAR_OPTION);
166
cmd.add(jarFile.getAbsolutePath());
167
for (String a : arg) {
168
cmd.add(a);
169
}
170
testProcessHelper(cmd, jarFile.getAbsolutePath());
171
}
172
}
173
174
}
175
176
// Test Java processes that are started with -m or --module options
177
// and with different combination of VM and program args.
178
private void testModule() throws Exception {
179
prepareModule();
180
for (String mp : MP_OPTIONS) {
181
for (String m : MODULE_OPTIONS) {
182
for (String[] vma : VM_ARGS) {
183
for (String[] arg : ARGS) {
184
for(String patchModuleOption : PATCH_MODULE_OPTIONS) {
185
List<String> cmd = new LinkedList<>();
186
cmd.add(JAVA_PATH);
187
cmd.add(mp);
188
cmd.add(TEST_MODULES.toAbsolutePath().toString());
189
if (patchModuleOption != null) {
190
cmd.add(patchModuleOption);
191
cmd.add(MODULE_NAME + "=" + TEST_MODULES.toAbsolutePath().toString());
192
}
193
for (String v : vma) {
194
cmd.add(v);
195
}
196
if (m.endsWith("=")) {
197
cmd.add(m + MODULE_NAME + "/" + TEST_PROCESS_MAIN_CLASS);
198
} else {
199
cmd.add(m);
200
cmd.add(MODULE_NAME + "/" + TEST_PROCESS_MAIN_CLASS);
201
}
202
for (String a : arg) {
203
cmd.add(a);
204
}
205
testProcessHelper(cmd, MODULE_NAME + "/" + TEST_PROCESS_MAIN_CLASS);
206
}
207
}
208
}
209
}
210
}
211
}
212
213
private void checkMainClass(Process p, String expectedMainClass) {
214
String mainClass = callGetMainClass(p);
215
// getMainClass() may return null, e.g. due to timing issues.
216
// Attempt some limited retries.
217
if (mainClass == null) {
218
System.err.println("Main class returned by ProcessHelper was null.");
219
// sleep time doubles each round, altogether, wait no longer than 1 sec
220
final int MAX_RETRIES = 10;
221
int retrycount = 0;
222
long sleepms = 1;
223
while (retrycount < MAX_RETRIES && mainClass == null) {
224
System.err.println("Retry " + retrycount + ", sleeping for " + sleepms + "ms.");
225
try {
226
Thread.sleep(sleepms);
227
} catch (InterruptedException e) {
228
// ignore
229
}
230
mainClass = callGetMainClass(p);
231
retrycount++;
232
sleepms *= 2;
233
}
234
}
235
p.destroyForcibly();
236
if (!expectedMainClass.equals(mainClass)) {
237
throw new RuntimeException("Main class is wrong: " + mainClass);
238
}
239
}
240
241
private void testProcessHelper(List<String> args, String expectedValue) throws Exception {
242
ProcessBuilder pb = new ProcessBuilder(args);
243
String cmd = pb.command().stream().collect(Collectors.joining(" "));
244
System.out.println("Starting the process:" + cmd);
245
Process p = ProcessTools.startProcess("test", pb);
246
if (!p.isAlive()) {
247
throw new RuntimeException("Cannot start the process: " + cmd);
248
}
249
checkMainClass(p, expectedValue);
250
}
251
252
private File prepareJar() throws Exception {
253
Path jarFile = USER_DIR.resolve("testprocess.jar");
254
Manifest manifest = createManifest();
255
JarUtils.createJarFile(jarFile, manifest, TEST_CLASSES, TEST_CLASS);
256
return jarFile.toFile();
257
}
258
259
private void prepareModule() throws Exception {
260
TEST_MODULES.toFile().mkdirs();
261
Path moduleJar = TEST_MODULES.resolve("mod1.jar");
262
ModuleDescriptor md = createModuleDescriptor();
263
createModuleJarFile(moduleJar, md, TEST_CLASSES, TEST_CLASS);
264
}
265
266
private Manifest createManifest() {
267
Manifest manifest = new Manifest();
268
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
269
manifest.getMainAttributes().put(Attributes.Name.MAIN_CLASS, TEST_PROCESS_MAIN_CLASS);
270
return manifest;
271
}
272
273
private ModuleDescriptor createModuleDescriptor() {
274
ModuleDescriptor.Builder builder
275
= ModuleDescriptor.newModule(MODULE_NAME).requires("java.base");
276
return builder.build();
277
}
278
279
private static void createModuleJarFile(Path jarfile, ModuleDescriptor md, Path dir, Path... files)
280
throws IOException {
281
282
Path parent = jarfile.getParent();
283
if (parent != null) {
284
Files.createDirectories(parent);
285
}
286
287
List<Path> entries = findAllRegularFiles(dir, files);
288
289
try (OutputStream out = Files.newOutputStream(jarfile);
290
JarOutputStream jos = new JarOutputStream(out)) {
291
if (md != null) {
292
JarEntry je = new JarEntry("module-info.class");
293
jos.putNextEntry(je);
294
ModuleInfoWriter.write(md, jos);
295
jos.closeEntry();
296
}
297
298
for (Path entry : entries) {
299
String name = toJarEntryName(entry);
300
jos.putNextEntry(new JarEntry(name));
301
Files.copy(dir.resolve(entry), jos);
302
jos.closeEntry();
303
}
304
}
305
}
306
307
private static String toJarEntryName(Path file) {
308
Path normalized = file.normalize();
309
return normalized.subpath(0, normalized.getNameCount())
310
.toString()
311
.replace(File.separatorChar, '/');
312
}
313
314
private static List<Path> findAllRegularFiles(Path dir, Path[] files) throws IOException {
315
List<Path> entries = new ArrayList<>();
316
for (Path file : files) {
317
try (Stream<Path> stream = Files.find(dir.resolve(file), Integer.MAX_VALUE,
318
(p, attrs) -> attrs.isRegularFile())) {
319
stream.map(dir::relativize)
320
.forEach(entries::add);
321
}
322
}
323
return entries;
324
}
325
326
}
327
328