1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.jlink;
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 import java.io.File;
41 import java.util.List;
42 import java.util.NoSuchElementException;
43 import java.util.Optional;
44
45 import org.apache.commons.lang3.StringUtils;
46 import org.apache.commons.lang3.SystemUtils;
47 import org.apache.maven.plugin.MojoExecutionException;
48 import org.apache.maven.plugin.logging.Log;
49 import org.apache.maven.shared.utils.cli.CommandLineException;
50 import org.apache.maven.shared.utils.cli.CommandLineUtils;
51 import org.apache.maven.shared.utils.cli.Commandline;
52 import org.apache.maven.toolchain.Toolchain;
53
54 abstract class AbstractJLinkToolchainExecutor extends AbstractJLinkExecutor {
55 private final Toolchain toolchain;
56
57 AbstractJLinkToolchainExecutor(Toolchain toolchain, Log log) {
58 super(log);
59 this.toolchain = toolchain;
60 }
61
62 protected Optional<Toolchain> getToolchain() {
63 return Optional.ofNullable(this.toolchain);
64 }
65
66
67
68
69
70
71 @Override
72 public int executeJlink(List<String> jlinkArgs) throws MojoExecutionException {
73 File jlinkExecutable = getJlinkExecutable();
74 getLog().info("Toolchain in maven-jlink-plugin: jlink [ " + jlinkExecutable + " ]");
75
76 Commandline cmd = createJLinkCommandLine(jlinkArgs);
77 cmd.setExecutable(jlinkExecutable.getAbsolutePath());
78
79 return executeCommand(cmd);
80 }
81
82 private File getJlinkExecutable() {
83 return new File(getJLinkExecutable());
84 }
85
86 @Override
87 public Optional<File> getJmodsFolder( File sourceJdkModules) {
88
89 File jLinkParent = getJlinkExecutable().getParentFile().getParentFile();
90 File jmodsFolder;
91 if (sourceJdkModules != null && sourceJdkModules.isDirectory()) {
92 jmodsFolder = new File(sourceJdkModules, JMODS);
93 } else {
94 jmodsFolder = new File(jLinkParent, JMODS);
95 }
96
97 getLog().debug(" Parent: " + jLinkParent.getAbsolutePath());
98 getLog().debug(" jmodsFolder: " + jmodsFolder.getAbsolutePath());
99
100 return Optional.of(jmodsFolder);
101 }
102
103 private Commandline createJLinkCommandLine(List<String> jlinkArgs) {
104 Commandline cmd = new Commandline();
105 jlinkArgs.forEach(arg -> cmd.createArg().setValue("\"" + arg + "\""));
106
107 return cmd;
108 }
109
110 private String getJLinkExecutable() {
111 Optional<Toolchain> toolchain = getToolchain();
112
113 if (!toolchain.isPresent()) {
114 getLog().error("Either JDK9+ or a toolchain "
115 + "pointing to a JDK9+ containing a jlink binary is required.");
116 getLog().info("See https://maven.apache.org/guides/mini/guide-using-toolchains.html "
117 + "for mor information.");
118 throw new IllegalStateException("Running on JDK8 and no toolchain found.");
119 }
120
121 String jLinkExecutable =
122 toolchain.orElseThrow(NoSuchElementException::new).findTool("jlink");
123
124 if (jLinkExecutable.isEmpty()) {
125 throw new IllegalStateException(
126 "The jlink executable '" + jLinkExecutable + "' doesn't exist or is not a file.");
127 }
128
129
130 String jLinkCommand = "jlink" + (SystemUtils.IS_OS_WINDOWS ? ".exe" : "");
131
132 File jLinkExe = new File(jLinkExecutable);
133
134 if (jLinkExe.isDirectory()) {
135 jLinkExe = new File(jLinkExe, jLinkCommand);
136 }
137
138 if (SystemUtils.IS_OS_WINDOWS && jLinkExe.getName().indexOf('.') < 0) {
139 jLinkExe = new File(jLinkExe.getPath() + ".exe");
140 }
141
142 if (!jLinkExe.isFile()) {
143 throw new IllegalStateException("The jlink executable '" + jLinkExe + "' doesn't exist or is not a file.");
144 }
145 return jLinkExe.getAbsolutePath();
146 }
147
148 private int executeCommand(Commandline cmd) throws MojoExecutionException {
149 if (getLog().isDebugEnabled()) {
150
151 getLog().debug(CommandLineUtils.toString(cmd.getCommandline()).replaceAll("'", ""));
152 }
153
154 CommandLineUtils.StringStreamConsumer err = new CommandLineUtils.StringStreamConsumer();
155 CommandLineUtils.StringStreamConsumer out = new CommandLineUtils.StringStreamConsumer();
156 try {
157 int exitCode = CommandLineUtils.executeCommandLine(cmd, out, err);
158
159 String output = StringUtils.isEmpty(out.getOutput())
160 ? null
161 : '\n' + out.getOutput().trim();
162
163 if (exitCode != 0) {
164
165 if (output != null && !output.isEmpty()) {
166
167
168 for (String outputLine : output.split("\n")) {
169 getLog().error(outputLine);
170 }
171 }
172
173 StringBuilder msg = new StringBuilder("\nExit code: ");
174 msg.append(exitCode);
175 if (StringUtils.isNotEmpty(err.getOutput())) {
176 msg.append(" - ").append(err.getOutput());
177 }
178 msg.append('\n');
179 msg.append("Command line was: ").append(cmd).append('\n').append('\n');
180
181 throw new MojoExecutionException(msg.toString());
182 }
183
184 if (output != null && !output.isEmpty()) {
185
186 for (String outputLine : output.split("\n")) {
187 getLog().info(outputLine);
188 }
189 }
190
191 return exitCode;
192 } catch (CommandLineException e) {
193 throw new MojoExecutionException("Unable to execute jlink command: " + e.getMessage(), e);
194 }
195 }
196 }