Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/tools/lib/tests/JImageGenerator.java
41149 views
1
/*
2
* Copyright (c) 2015, 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
package tests;
24
25
import java.io.ByteArrayInputStream;
26
import java.io.ByteArrayOutputStream;
27
import java.io.File;
28
import java.io.FileOutputStream;
29
import java.io.IOException;
30
import java.io.InputStream;
31
import java.io.OutputStream;
32
import java.io.PrintStream;
33
import java.io.PrintWriter;
34
import java.io.StringWriter;
35
import java.nio.file.Files;
36
import java.nio.file.Path;
37
import java.nio.file.Paths;
38
import java.nio.file.StandardCopyOption;
39
import java.util.ArrayList;
40
import java.util.Arrays;
41
import java.util.Collections;
42
import java.util.HashSet;
43
import java.util.List;
44
import java.util.Objects;
45
import java.util.Set;
46
import java.util.jar.JarEntry;
47
import java.util.jar.JarInputStream;
48
import java.util.jar.JarOutputStream;
49
import java.util.stream.Collectors;
50
import java.util.stream.Stream;
51
import java.util.zip.ZipEntry;
52
53
import javax.tools.JavaCompiler;
54
import javax.tools.StandardJavaFileManager;
55
import javax.tools.StandardLocation;
56
import javax.tools.ToolProvider;
57
58
/**
59
*
60
* A generator for jmods, jars and images.
61
*/
62
public class JImageGenerator {
63
64
public static final String LOAD_ALL_CLASSES_TEMPLATE = "package PACKAGE;\n"
65
+ "\n"
66
+ "import java.net.URI;\n"
67
+ "import java.nio.file.FileSystems;\n"
68
+ "import java.nio.file.Files;\n"
69
+ "import java.nio.file.Path;\n"
70
+ "import java.util.function.Function;\n"
71
+ "\n"
72
+ "public class CLASS {\n"
73
+ " private static long total_time;\n"
74
+ " private static long num_classes;\n"
75
+ " public static void main(String[] args) throws Exception {\n"
76
+ " Function<Path, String> formatter = (path) -> {\n"
77
+ " String clazz = path.toString().substring(\"modules/\".length()+1, path.toString().lastIndexOf(\".\"));\n"
78
+ " clazz = clazz.substring(clazz.indexOf(\"/\") + 1);\n"
79
+ " return clazz.replaceAll(\"/\", \"\\\\.\");\n"
80
+ " };\n"
81
+ " Files.walk(FileSystems.getFileSystem(URI.create(\"jrt:/\")).getPath(\"/modules/\")).\n"
82
+ " filter((p) -> {\n"
83
+ " return Files.isRegularFile(p) && p.toString().endsWith(\".class\")\n"
84
+ " && !p.toString().endsWith(\"module-info.class\");\n"
85
+ " }).\n"
86
+ " map(formatter).forEach((clazz) -> {\n"
87
+ " try {\n"
88
+ " long t = System.currentTimeMillis();\n"
89
+ " Class.forName(clazz, false, Thread.currentThread().getContextClassLoader());\n"
90
+ " total_time+= System.currentTimeMillis()-t;\n"
91
+ " num_classes+=1;\n"
92
+ " } catch (IllegalAccessError ex) {\n"
93
+ " // Security exceptions can occur, this is not what we are testing\n"
94
+ " System.err.println(\"Access error, OK \" + clazz);\n"
95
+ " } catch (Exception ex) {\n"
96
+ " System.err.println(\"ERROR \" + clazz);\n"
97
+ " throw new RuntimeException(ex);\n"
98
+ " }\n"
99
+ " });\n"
100
+ " double res = (double) total_time / num_classes;\n"
101
+ " // System.out.println(\"Total time \" + total_time + \" num classes \" + num_classes + \" average \" + res);\n"
102
+ " }\n"
103
+ "}\n";
104
105
private static final String OUTPUT_OPTION = "--output";
106
private static final String POST_PROCESS_OPTION = "--post-process-path";
107
private static final String MAIN_CLASS_OPTION = "--main-class";
108
private static final String CLASS_PATH_OPTION = "--class-path";
109
private static final String MODULE_PATH_OPTION = "--module-path";
110
private static final String ADD_MODULES_OPTION = "--add-modules";
111
private static final String LIMIT_MODULES_OPTION = "--limit-modules";
112
private static final String PLUGIN_MODULE_PATH = "--plugin-module-path";
113
private static final String LAUNCHER = "--launcher";
114
115
private static final String CMDS_OPTION = "--cmds";
116
private static final String CONFIG_OPTION = "--config";
117
private static final String HASH_MODULES_OPTION = "--hash-modules";
118
private static final String LIBS_OPTION = "--libs";
119
private static final String MODULE_VERSION_OPTION = "--module-version";
120
121
private JImageGenerator() {}
122
123
private static String optionsPrettyPrint(String... args) {
124
return Stream.of(args).collect(Collectors.joining(" "));
125
}
126
127
public static File getJModsDir(File jdkHome) {
128
File jdkjmods = new File(jdkHome, "jmods");
129
if (!jdkjmods.exists()) {
130
return null;
131
}
132
return jdkjmods;
133
}
134
135
public static Path addFiles(Path module, InMemoryFile... resources) throws IOException {
136
Path tempFile = Files.createTempFile("jlink-test", "");
137
try (JarInputStream in = new JarInputStream(Files.newInputStream(module));
138
JarOutputStream out = new JarOutputStream(new FileOutputStream(tempFile.toFile()))) {
139
ZipEntry entry;
140
while ((entry = in.getNextEntry()) != null) {
141
String name = entry.getName();
142
out.putNextEntry(new ZipEntry(name));
143
copy(in, out);
144
out.closeEntry();
145
}
146
for (InMemoryFile r : resources) {
147
addFile(r, out);
148
}
149
}
150
Files.move(tempFile, module, StandardCopyOption.REPLACE_EXISTING);
151
return module;
152
}
153
154
private static void copy(InputStream in, OutputStream out) throws IOException {
155
int len;
156
byte[] buf = new byte[4096];
157
while ((len = in.read(buf)) > 0) {
158
out.write(buf, 0, len);
159
}
160
}
161
162
public static JModTask getJModTask() {
163
return new JModTask();
164
}
165
166
public static JLinkTask getJLinkTask() {
167
return new JLinkTask();
168
}
169
170
public static JImageTask getJImageTask() {
171
return new JImageTask();
172
}
173
174
private static void addFile(InMemoryFile resource, JarOutputStream target) throws IOException {
175
String fileName = resource.getPath();
176
fileName = fileName.replace("\\", "/");
177
String[] ss = fileName.split("/");
178
Path p = Paths.get("");
179
for (int i = 0; i < ss.length; ++i) {
180
if (i < ss.length - 1) {
181
if (!ss[i].isEmpty()) {
182
p = p.resolve(ss[i]);
183
JarEntry entry = new JarEntry(p.toString() + "/");
184
target.putNextEntry(entry);
185
target.closeEntry();
186
}
187
} else {
188
p = p.resolve(ss[i]);
189
JarEntry entry = new JarEntry(p.toString());
190
target.putNextEntry(entry);
191
copy(resource.getBytes(), target);
192
target.closeEntry();
193
}
194
}
195
}
196
197
public static Path createNewFile(Path root, String pathName, String extension) {
198
Path out = root.resolve(pathName + extension);
199
int i = 1;
200
while (Files.exists(out)) {
201
out = root.resolve(pathName + "-" + (++i) + extension);
202
}
203
return out;
204
}
205
206
public static Path generateSources(Path output, String moduleName, List<InMemorySourceFile> sources) throws IOException {
207
Path moduleDir = output.resolve(moduleName);
208
Files.createDirectory(moduleDir);
209
for (InMemorySourceFile source : sources) {
210
Path fileDir = moduleDir;
211
if (!source.packageName.isEmpty()) {
212
String dir = source.packageName.replace('.', File.separatorChar);
213
fileDir = moduleDir.resolve(dir);
214
Files.createDirectories(fileDir);
215
}
216
Files.write(fileDir.resolve(source.className + ".java"), source.source.getBytes());
217
}
218
return moduleDir;
219
}
220
221
public static Path generateSourcesFromTemplate(Path output, String moduleName, String... classNames) throws IOException {
222
List<InMemorySourceFile> sources = new ArrayList<>();
223
for (String className : classNames) {
224
String packageName = getPackageName(className);
225
String simpleName = getSimpleName(className);
226
String content = LOAD_ALL_CLASSES_TEMPLATE
227
.replace("CLASS", simpleName);
228
if (packageName.isEmpty()) {
229
content = content.replace("package PACKAGE;", packageName);
230
} else {
231
content = content.replace("PACKAGE", packageName);
232
}
233
sources.add(new InMemorySourceFile(packageName, simpleName, content));
234
}
235
return generateSources(output, moduleName, sources);
236
}
237
238
public static void generateModuleInfo(Path moduleDir, List<String> packages, String... dependencies) throws IOException {
239
StringBuilder moduleInfoBuilder = new StringBuilder();
240
Path file = moduleDir.resolve("module-info.java");
241
String moduleName = moduleDir.getFileName().toString();
242
moduleInfoBuilder.append("module ").append(moduleName).append("{\n");
243
for (String dep : dependencies) {
244
moduleInfoBuilder.append("requires ").append(dep).append(";\n");
245
}
246
for (String pkg : packages) {
247
if (!pkg.trim().isEmpty()) {
248
moduleInfoBuilder.append("exports ").append(pkg).append(";\n");
249
}
250
}
251
moduleInfoBuilder.append("}");
252
Files.write(file, moduleInfoBuilder.toString().getBytes());
253
}
254
255
public static void compileSuccess(Path source, Path destination, String... options) throws IOException {
256
if (!compile(source, destination, options)) {
257
throw new AssertionError("Compilation failed.");
258
}
259
}
260
261
public static boolean compile(Path source, Path destination, String... options) throws IOException {
262
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
263
try (StandardJavaFileManager jfm = compiler.getStandardFileManager(null, null, null)) {
264
List<Path> sources
265
= Files.find(source, Integer.MAX_VALUE,
266
(file, attrs) -> file.toString().endsWith(".java"))
267
.collect(Collectors.toList());
268
269
Files.createDirectories(destination);
270
jfm.setLocationFromPaths(StandardLocation.CLASS_OUTPUT, Collections.singleton(destination));
271
272
List<String> opts = Arrays.asList(options);
273
JavaCompiler.CompilationTask task
274
= compiler.getTask(null, jfm, null, opts, null,
275
jfm.getJavaFileObjectsFromPaths(sources));
276
List<String> list = new ArrayList<>(opts);
277
list.addAll(sources.stream()
278
.map(Path::toString)
279
.collect(Collectors.toList()));
280
System.err.println("javac options: " + optionsPrettyPrint(list.toArray(new String[list.size()])));
281
return task.call();
282
}
283
}
284
285
public static Path createJarFile(Path jarfile, Path dir) throws IOException {
286
return createJarFile(jarfile, dir, Paths.get("."));
287
}
288
289
public static Path createJarFile(Path jarfile, Path dir, Path file) throws IOException {
290
// create the target directory
291
Path parent = jarfile.getParent();
292
if (parent != null)
293
Files.createDirectories(parent);
294
295
List<Path> entries = Files.find(dir.resolve(file), Integer.MAX_VALUE,
296
(p, attrs) -> attrs.isRegularFile())
297
.map(dir::relativize)
298
.collect(Collectors.toList());
299
300
try (OutputStream out = Files.newOutputStream(jarfile);
301
JarOutputStream jos = new JarOutputStream(out)) {
302
for (Path entry : entries) {
303
// map the file path to a name in the JAR file
304
Path normalized = entry.normalize();
305
String name = normalized
306
.subpath(0, normalized.getNameCount()) // drop root
307
.toString()
308
.replace(File.separatorChar, '/');
309
310
jos.putNextEntry(new JarEntry(name));
311
Files.copy(dir.resolve(entry), jos);
312
}
313
}
314
return jarfile;
315
}
316
317
public static Set<String> getModuleContent(Path module) {
318
Result result = JImageGenerator.getJModTask()
319
.jmod(module)
320
.list();
321
result.assertSuccess();
322
return Stream.of(result.getMessage().split("\r?\n"))
323
.collect(Collectors.toSet());
324
}
325
326
public static void checkModule(Path module, Set<String> expected) throws IOException {
327
Set<String> actual = getModuleContent(module);
328
if (!Objects.equals(actual, expected)) {
329
Set<String> unexpected = new HashSet<>(actual);
330
unexpected.removeAll(expected);
331
Set<String> notFound = new HashSet<>(expected);
332
notFound.removeAll(actual);
333
System.err.println("Unexpected files:");
334
unexpected.forEach(s -> System.err.println("\t" + s));
335
System.err.println("Not found files:");
336
notFound.forEach(s -> System.err.println("\t" + s));
337
throw new AssertionError("Module check failed.");
338
}
339
}
340
341
public static class JModTask {
342
static final java.util.spi.ToolProvider JMOD_TOOL =
343
java.util.spi.ToolProvider.findFirst("jmod").orElseThrow(() ->
344
new RuntimeException("jmod tool not found")
345
);
346
347
private final List<Path> classpath = new ArrayList<>();
348
private final List<Path> libs = new ArrayList<>();
349
private final List<Path> cmds = new ArrayList<>();
350
private final List<Path> config = new ArrayList<>();
351
private final List<Path> jars = new ArrayList<>();
352
private final List<Path> jmods = new ArrayList<>();
353
private final List<String> options = new ArrayList<>();
354
private Path output;
355
private String hashModules;
356
private String mainClass;
357
private String moduleVersion;
358
359
public JModTask addNativeLibraries(Path cp) {
360
this.libs.add(cp);
361
return this;
362
}
363
364
public JModTask hashModules(String hash) {
365
this.hashModules = hash;
366
return this;
367
}
368
369
public JModTask addCmds(Path cp) {
370
this.cmds.add(cp);
371
return this;
372
}
373
374
public JModTask addClassPath(Path cp) {
375
this.classpath.add(cp);
376
return this;
377
}
378
379
public JModTask addConfig(Path cp) {
380
this.config.add(cp);
381
return this;
382
}
383
384
public JModTask addJars(Path jars) {
385
this.jars.add(jars);
386
return this;
387
}
388
389
public JModTask addJmods(Path jmods) {
390
this.jmods.add(jmods);
391
return this;
392
}
393
394
public JModTask jmod(Path output) {
395
this.output = output;
396
return this;
397
}
398
399
public JModTask moduleVersion(String moduleVersion) {
400
this.moduleVersion = moduleVersion;
401
return this;
402
}
403
404
public JModTask mainClass(String mainClass) {
405
this.mainClass = mainClass;
406
return this;
407
}
408
409
public JModTask option(String o) {
410
this.options.add(o);
411
return this;
412
}
413
414
private String modulePath() {
415
// This is expect FIRST jmods THEN jars, if you change this, some tests could fail
416
String jmods = toPath(this.jmods);
417
String jars = toPath(this.jars);
418
return jmods + File.pathSeparator + jars;
419
}
420
421
private String toPath(List<Path> paths) {
422
return paths.stream()
423
.map(Path::toString)
424
.collect(Collectors.joining(File.pathSeparator));
425
}
426
427
private String[] optionsJMod(String cmd) {
428
List<String> options = new ArrayList<>();
429
options.add(cmd);
430
if (!cmds.isEmpty()) {
431
options.add(CMDS_OPTION);
432
options.add(toPath(cmds));
433
}
434
if (!config.isEmpty()) {
435
options.add(CONFIG_OPTION);
436
options.add(toPath(config));
437
}
438
if (hashModules != null) {
439
options.add(HASH_MODULES_OPTION);
440
options.add(hashModules);
441
}
442
if (mainClass != null) {
443
options.add(MAIN_CLASS_OPTION);
444
options.add(mainClass);
445
}
446
if (!libs.isEmpty()) {
447
options.add(LIBS_OPTION);
448
options.add(toPath(libs));
449
}
450
if (!classpath.isEmpty()) {
451
options.add(CLASS_PATH_OPTION);
452
options.add(toPath(classpath));
453
}
454
if (!jars.isEmpty() || !jmods.isEmpty()) {
455
options.add(MODULE_PATH_OPTION);
456
options.add(modulePath());
457
}
458
if (moduleVersion != null) {
459
options.add(MODULE_VERSION_OPTION);
460
options.add(moduleVersion);
461
}
462
options.addAll(this.options);
463
if (output != null) {
464
options.add(output.toString());
465
}
466
return options.toArray(new String[options.size()]);
467
}
468
469
public Result create() {
470
return cmd("create");
471
}
472
473
public Result list() {
474
return cmd("list");
475
}
476
477
public Result call() {
478
return cmd("");
479
}
480
481
private Result cmd(String cmd) {
482
String[] args = optionsJMod(cmd);
483
System.err.println("jmod options: " + optionsPrettyPrint(args));
484
ByteArrayOutputStream baos = new ByteArrayOutputStream();
485
PrintStream ps = new PrintStream(baos);
486
int exitCode = JMOD_TOOL.run(ps, ps, args);
487
String msg = new String(baos.toByteArray());
488
return new Result(exitCode, msg, output);
489
}
490
}
491
492
public static String getPackageName(String canonicalName) {
493
int index = canonicalName.lastIndexOf('.');
494
return index > 0 ? canonicalName.substring(0, index) : "";
495
}
496
497
public static String getSimpleName(String canonicalName) {
498
int index = canonicalName.lastIndexOf('.');
499
return canonicalName.substring(index + 1);
500
}
501
502
public static class JImageTask {
503
504
private final List<Path> pluginModulePath = new ArrayList<>();
505
private final List<String> options = new ArrayList<>();
506
private Path dir;
507
private Path image;
508
509
public JImageTask pluginModulePath(Path p) {
510
this.pluginModulePath.add(p);
511
return this;
512
}
513
514
public JImageTask image(Path image) {
515
this.image = image;
516
return this;
517
}
518
519
public JImageTask dir(Path dir) {
520
this.dir = dir;
521
return this;
522
}
523
524
public JImageTask option(String o) {
525
this.options.add(o);
526
return this;
527
}
528
529
private String toPath(List<Path> paths) {
530
return paths.stream()
531
.map(Path::toString)
532
.collect(Collectors.joining(File.pathSeparator));
533
}
534
535
private String[] optionsJImage(String cmd) {
536
List<String> options = new ArrayList<>();
537
options.add(cmd);
538
if (dir != null) {
539
options.add("--dir");
540
options.add(dir.toString());
541
}
542
if (!pluginModulePath.isEmpty()) {
543
options.add(PLUGIN_MODULE_PATH);
544
options.add(toPath(pluginModulePath));
545
}
546
options.addAll(this.options);
547
options.add(image.toString());
548
return options.toArray(new String[options.size()]);
549
}
550
551
private Result cmd(String cmd, Path returnPath) {
552
String[] args = optionsJImage(cmd);
553
System.err.println("jimage options: " + optionsPrettyPrint(args));
554
StringWriter writer = new StringWriter();
555
int exitCode = jdk.tools.jimage.Main.run(args, new PrintWriter(writer));
556
return new Result(exitCode, writer.toString(), returnPath);
557
}
558
559
public Result extract() {
560
return cmd("extract", dir);
561
}
562
}
563
564
public static class JLinkTask {
565
static final java.util.spi.ToolProvider JLINK_TOOL =
566
java.util.spi.ToolProvider.findFirst("jlink").orElseThrow(() ->
567
new RuntimeException("jlink tool not found")
568
);
569
570
private final List<Path> jars = new ArrayList<>();
571
private final List<Path> jmods = new ArrayList<>();
572
private final List<Path> pluginModulePath = new ArrayList<>();
573
private final List<String> addMods = new ArrayList<>();
574
private final List<String> limitMods = new ArrayList<>();
575
private final List<String> options = new ArrayList<>();
576
private String modulePath;
577
// if you want to specifiy repeated --module-path option
578
private String repeatedModulePath;
579
// if you want to specifiy repeated --limit-modules option
580
private String repeatedLimitMods;
581
private Path output;
582
private Path existing;
583
private String launcher; // optional
584
585
public JLinkTask modulePath(String modulePath) {
586
this.modulePath = modulePath;
587
return this;
588
}
589
590
public JLinkTask launcher(String cmd) {
591
launcher = Objects.requireNonNull(cmd);
592
return this;
593
}
594
595
public JLinkTask repeatedModulePath(String modulePath) {
596
this.repeatedModulePath = modulePath;
597
return this;
598
}
599
600
public JLinkTask addJars(Path jars) {
601
this.jars.add(jars);
602
return this;
603
}
604
605
public JLinkTask addJmods(Path jmods) {
606
this.jmods.add(jmods);
607
return this;
608
}
609
610
public JLinkTask pluginModulePath(Path p) {
611
this.pluginModulePath.add(p);
612
return this;
613
}
614
615
public JLinkTask addMods(String moduleName) {
616
this.addMods.add(moduleName);
617
return this;
618
}
619
620
public JLinkTask limitMods(String moduleName) {
621
this.limitMods.add(moduleName);
622
return this;
623
}
624
625
public JLinkTask repeatedLimitMods(String modules) {
626
this.repeatedLimitMods = modules;
627
return this;
628
}
629
630
public JLinkTask output(Path output) {
631
this.output = output;
632
return this;
633
}
634
635
public JLinkTask existing(Path existing) {
636
this.existing = existing;
637
return this;
638
}
639
640
public JLinkTask option(String o) {
641
this.options.add(o);
642
return this;
643
}
644
645
private String modulePath() {
646
// This is expect FIRST jmods THEN jars, if you change this, some tests could fail
647
String jmods = toPath(this.jmods);
648
String jars = toPath(this.jars);
649
return jmods + File.pathSeparator + jars;
650
}
651
652
private String toPath(List<Path> paths) {
653
return paths.stream()
654
.map(Path::toString)
655
.collect(Collectors.joining(File.pathSeparator));
656
}
657
658
private String[] optionsJLink() {
659
List<String> options = new ArrayList<>();
660
if (output != null) {
661
options.add(OUTPUT_OPTION);
662
options.add(output.toString());
663
}
664
if (!addMods.isEmpty()) {
665
options.add(ADD_MODULES_OPTION);
666
options.add(addMods.stream().collect(Collectors.joining(",")));
667
}
668
if (!limitMods.isEmpty()) {
669
options.add(LIMIT_MODULES_OPTION);
670
options.add(limitMods.stream().collect(Collectors.joining(",")));
671
}
672
if (repeatedLimitMods != null) {
673
options.add(LIMIT_MODULES_OPTION);
674
options.add(repeatedLimitMods);
675
}
676
if (!jars.isEmpty() || !jmods.isEmpty()) {
677
options.add(MODULE_PATH_OPTION);
678
options.add(modulePath());
679
}
680
if (modulePath != null) {
681
options.add(MODULE_PATH_OPTION);
682
options.add(modulePath);
683
}
684
if (repeatedModulePath != null) {
685
options.add(MODULE_PATH_OPTION);
686
options.add(repeatedModulePath);
687
}
688
if (!pluginModulePath.isEmpty()) {
689
options.add(PLUGIN_MODULE_PATH);
690
options.add(toPath(pluginModulePath));
691
}
692
if (launcher != null && !launcher.isEmpty()) {
693
options.add(LAUNCHER);
694
options.add(launcher);
695
}
696
options.addAll(this.options);
697
return options.toArray(new String[options.size()]);
698
}
699
700
private String[] optionsPostProcessJLink() {
701
List<String> options = new ArrayList<>();
702
if (existing != null) {
703
options.add(POST_PROCESS_OPTION);
704
options.add(existing.toString());
705
}
706
options.addAll(this.options);
707
return options.toArray(new String[options.size()]);
708
}
709
710
public Result call() {
711
String[] args = optionsJLink();
712
System.err.println("jlink options: " + optionsPrettyPrint(args));
713
StringWriter writer = new StringWriter();
714
PrintWriter pw = new PrintWriter(writer);
715
int exitCode = JLINK_TOOL.run(pw, pw, args);
716
return new Result(exitCode, writer.toString(), output);
717
}
718
719
public Result callPostProcess() {
720
String[] args = optionsPostProcessJLink();
721
System.err.println("jlink options: " + optionsPrettyPrint(args));
722
StringWriter writer = new StringWriter();
723
PrintWriter pw = new PrintWriter(writer);
724
int exitCode = JLINK_TOOL.run(pw, pw, args);
725
return new Result(exitCode, writer.toString(), output);
726
}
727
}
728
729
public static class InMemorySourceFile {
730
public final String packageName;
731
public final String className;
732
public final String source;
733
734
public InMemorySourceFile(String packageName, String simpleName, String source) {
735
this.packageName = packageName;
736
this.className = simpleName;
737
this.source = source;
738
}
739
}
740
741
public static class InMemoryFile {
742
private final String path;
743
private final byte[] bytes;
744
745
public String getPath() {
746
return path;
747
}
748
749
public InputStream getBytes() {
750
return new ByteArrayInputStream(bytes);
751
}
752
753
public InMemoryFile(String path, byte[] bytes) {
754
this.path = path;
755
this.bytes = bytes;
756
}
757
758
public InMemoryFile(String path, InputStream is) throws IOException {
759
this(path, readAllBytes(is));
760
}
761
}
762
763
public static byte[] readAllBytes(InputStream is) throws IOException {
764
ByteArrayOutputStream baos = new ByteArrayOutputStream();
765
byte[] buf = new byte[1024];
766
while (true) {
767
int n = is.read(buf);
768
if (n < 0) {
769
break;
770
}
771
baos.write(buf, 0, n);
772
}
773
return baos.toByteArray();
774
}
775
}
776
777