1 /*
2 * Copyright (c) 2021, 2026, 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package jdk.tools.jlink.internal.plugins;
26
27 import java.io.IOException;
28 import java.nio.file.Files;
29 import java.nio.file.Path;
30 import java.util.*;
31
32 import jdk.internal.util.Architecture;
33 import jdk.internal.util.OperatingSystem;
34 import jdk.tools.jlink.internal.ExecutableImage;
35 import jdk.tools.jlink.internal.Platform;
36 import jdk.tools.jlink.internal.PostProcessor;
37 import jdk.tools.jlink.plugin.PluginException;
38 import jdk.tools.jlink.plugin.ResourcePool;
39 import jdk.tools.jlink.plugin.ResourcePoolBuilder;
40
41 /**
42 *
43 * CDS plugin
44 */
45 public final class CDSPlugin extends AbstractPlugin implements PostProcessor {
46 private static final String NAME = "generate-cds-archive";
47 private Platform targetPlatform;
48 private Platform runtimePlatform;
49
50 public CDSPlugin() {
51 super(NAME);
52 }
53
54
55 private String javaExecutableName() {
56 if (targetPlatform.os() == OperatingSystem.WINDOWS) {
57 return "java.exe";
58 } else {
59 return "java";
60 }
61 }
62
63 private void generateCDSArchive(ExecutableImage image, boolean noCoops, boolean noCoh) {
64 List<String> javaCmd = new ArrayList<String>();
65 Path javaPath = image.getHome().resolve("bin").resolve(javaExecutableName());
66 if (!Files.exists(javaPath)) {
67 throw new PluginException("Cannot find java executable at: " + javaPath.toString());
68 }
69 javaCmd.add(javaPath.toString());
70 javaCmd.add("-Xshare:dump");
71 String archiveMsg = "CDS";
72 if (noCoops) {
73 javaCmd.add("-XX:-UseCompressedOops");
74 archiveMsg += "-NOCOOPS";
75 }
76 if (noCoh) {
77 javaCmd.add("-XX:-UseCompactObjectHeaders");
78 archiveMsg += "-NOCOH";
79 }
80 ProcessBuilder builder = new ProcessBuilder(javaCmd);
81 int status = -1;
82 try {
83 Process p = builder.inheritIO().start();
84 status = p.waitFor();
85 } catch (InterruptedException | IOException e) {
86 throw new PluginException(e);
87 }
88
89 if (status != 0) {
90 throw new PluginException("Failed creating " + archiveMsg + " archive!");
91 }
92 }
93
94 @Override
95 public List<String> process(ExecutableImage image) {
96 targetPlatform = image.getTargetPlatform();
97 runtimePlatform = Platform.runtime();
98
99 if (!targetPlatform.equals(runtimePlatform)) {
100 throw new PluginException("Cannot generate CDS archives: target image platform " +
101 targetPlatform.toString() + " is different from runtime platform " +
102 runtimePlatform.toString());
103 }
104
105 Path classListPath = image.getHome().resolve("lib").resolve("classlist");
106 if (Files.exists(classListPath)) {
107 generateCDSArchive(image, false, false);
108
109 // Generate all of the CDS archive combinations: nocoops, nocoh, nocoops_nocoh.
110 if (Architecture.is64bit()) {
111 generateCDSArchive(image, true, false);
112 generateCDSArchive(image, false, true);
113 generateCDSArchive(image, true, true);
114 }
115 System.out.println("Created CDS archive successfully");
116 } else {
117 throw new PluginException("Cannot generate CDS archives: classlist not found: " +
118 classListPath.toString());
119 }
120 return null;
121 }
122
123 @Override
124 public Category getType() {
125 return Category.PROCESSOR;
126 }
127
128 @Override
129 public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
130 return in;
131 }
132 }