73 * The default java executable Image.
74 */
75 static final class DefaultExecutableImage implements ExecutableImage {
76
77 private final Path home;
78 private final List<String> args;
79 private final Set<String> modules;
80
81 DefaultExecutableImage(Path home, Set<String> modules) {
82 Objects.requireNonNull(home);
83 if (!Files.exists(home)) {
84 throw new IllegalArgumentException("Invalid image home");
85 }
86 this.home = home;
87 this.modules = Collections.unmodifiableSet(modules);
88 this.args = createArgs(home);
89 }
90
91 private static List<String> createArgs(Path home) {
92 Objects.requireNonNull(home);
93 List<String> javaArgs = new ArrayList<>();
94 Path binDir = home.resolve("bin");
95 String java = Files.exists(binDir.resolve("java"))? "java" : "java.exe";
96 javaArgs.add(binDir.resolve(java).toString());
97 return Collections.unmodifiableList(javaArgs);
98 }
99
100 @Override
101 public Path getHome() {
102 return home;
103 }
104
105 @Override
106 public Set<String> getModules() {
107 return modules;
108 }
109
110 @Override
111 public List<String> getExecutionArgs() {
112 return args;
113 }
114
115 @Override
116 public void storeLaunchArgs(List<String> args) {
117 try {
153
154 private void addModules(Properties props, Set<String> modules) throws IOException {
155 StringBuilder builder = new StringBuilder();
156 int i = 0;
157 for (String m : modules) {
158 builder.append(m);
159 if (i < modules.size() - 1) {
160 builder.append(",");
161 }
162 i++;
163 }
164 props.setProperty("MODULES", builder.toString());
165 }
166
167 @Override
168 public void storeFiles(ResourcePool files) {
169 try {
170 // populate release properties up-front. targetOsName
171 // field is assigned from there and used elsewhere.
172 Properties release = releaseProperties(files);
173
174 files.entries().forEach(f -> {
175 if (!f.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
176 try {
177 accept(f);
178 } catch (IOException ioExp) {
179 throw new UncheckedIOException(ioExp);
180 }
181 }
182 });
183 files.moduleView().modules().forEach(m -> {
184 // Only add modules that contain packages
185 if (!m.packages().isEmpty()) {
186 modules.add(m.name());
187 }
188 });
189
190 storeFiles(modules, release);
191
192 if (Files.getFileStore(root).supportsFileAttributeView(PosixFileAttributeView.class)) {
193 // launchers in the bin directory need execute permission
194 Path bin = root.resolve("bin");
195 if (Files.isDirectory(bin)) {
196 Files.list(bin)
197 .filter(f -> !f.toString().endsWith(".diz"))
198 .filter(f -> Files.isRegularFile(f))
199 .forEach(this::setExecutable);
200 }
201
202 // jspawnhelper is in lib or lib/<arch>
203 Path lib = root.resolve("lib");
204 if (Files.isDirectory(lib)) {
205 Files.find(lib, 2, (path, attrs) -> {
206 return path.getFileName().toString().equals("jspawnhelper")
207 || path.getFileName().toString().equals("jexec");
208 }).forEach(this::setExecutable);
209 }
210 }
211
212 prepareApplicationFiles(files, modules);
213 } catch (IOException ex) {
214 throw new PluginException(ex);
215 }
216 }
217
218 private Properties releaseProperties(ResourcePool pool) throws IOException {
219 Properties props = new Properties();
220 Optional<ResourcePoolModule> javaBase = pool.moduleView().findModule("java.base");
221 javaBase.ifPresent(mod -> {
222 // fill release information available from transformed "java.base" module!
223 ModuleDescriptor desc = mod.descriptor();
224 desc.osName().ifPresent(s -> props.setProperty("OS_NAME", s));
225 desc.osVersion().ifPresent(s -> props.setProperty("OS_VERSION", s));
226 desc.osArch().ifPresent(s -> props.setProperty("OS_ARCH", s));
227 props.setProperty("JAVA_VERSION", System.getProperty("java.version"));
228 });
229
230 this.targetOsName = props.getProperty("OS_NAME");
231 if (this.targetOsName == null) {
232 throw new RuntimeException("can't determine target OS from java.base descriptor");
233 }
234
235 Optional<ResourcePoolEntry> release = pool.findEntry("/java.base/release");
236 if (release.isPresent()) {
237 try (InputStream is = release.get().content()) {
238 props.load(is);
239 }
240 }
241
242 return props;
243 }
244
245 /**
246 * Generates launcher scripts.
247 *
248 * @param imageContent The image content.
249 * @param modules The set of modules that the runtime image contains.
250 * @throws IOException
251 */
252 protected void prepareApplicationFiles(ResourcePool imageContent, Set<String> modules) throws IOException {
|
73 * The default java executable Image.
74 */
75 static final class DefaultExecutableImage implements ExecutableImage {
76
77 private final Path home;
78 private final List<String> args;
79 private final Set<String> modules;
80
81 DefaultExecutableImage(Path home, Set<String> modules) {
82 Objects.requireNonNull(home);
83 if (!Files.exists(home)) {
84 throw new IllegalArgumentException("Invalid image home");
85 }
86 this.home = home;
87 this.modules = Collections.unmodifiableSet(modules);
88 this.args = createArgs(home);
89 }
90
91 private static List<String> createArgs(Path home) {
92 Objects.requireNonNull(home);
93 Path binDir = home.resolve("bin");
94 String java = Files.exists(binDir.resolve("java"))? "java" : "java.exe";
95 return List.of(binDir.resolve(java).toString());
96 }
97
98 @Override
99 public Path getHome() {
100 return home;
101 }
102
103 @Override
104 public Set<String> getModules() {
105 return modules;
106 }
107
108 @Override
109 public List<String> getExecutionArgs() {
110 return args;
111 }
112
113 @Override
114 public void storeLaunchArgs(List<String> args) {
115 try {
151
152 private void addModules(Properties props, Set<String> modules) throws IOException {
153 StringBuilder builder = new StringBuilder();
154 int i = 0;
155 for (String m : modules) {
156 builder.append(m);
157 if (i < modules.size() - 1) {
158 builder.append(",");
159 }
160 i++;
161 }
162 props.setProperty("MODULES", builder.toString());
163 }
164
165 @Override
166 public void storeFiles(ResourcePool files) {
167 try {
168 // populate release properties up-front. targetOsName
169 // field is assigned from there and used elsewhere.
170 Properties release = releaseProperties(files);
171 Path bin = root.resolve("bin");
172
173 files.entries().forEach(f -> {
174 if (!f.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
175 try {
176 accept(f);
177 } catch (IOException ioExp) {
178 throw new UncheckedIOException(ioExp);
179 }
180 }
181 });
182 files.moduleView().modules().forEach(m -> {
183 // Only add modules that contain packages
184 if (!m.packages().isEmpty()) {
185 modules.add(m.name());
186 }
187 });
188
189 storeFiles(modules, release);
190
191 if (Files.getFileStore(root).supportsFileAttributeView(PosixFileAttributeView.class)) {
192 // launchers in the bin directory need execute permission
193 if (Files.isDirectory(bin)) {
194 Files.list(bin)
195 .filter(f -> !f.toString().endsWith(".diz"))
196 .filter(f -> Files.isRegularFile(f))
197 .forEach(this::setExecutable);
198 }
199
200 // jspawnhelper is in lib or lib/<arch>
201 Path lib = root.resolve("lib");
202 if (Files.isDirectory(lib)) {
203 Files.find(lib, 2, (path, attrs) -> {
204 return path.getFileName().toString().equals("jspawnhelper")
205 || path.getFileName().toString().equals("jexec");
206 }).forEach(this::setExecutable);
207 }
208 }
209
210 // If native files are stripped completely, <root>/bin dir won't exist!
211 // So, don't bother generating launcher scripts.
212 if (Files.isDirectory(bin)) {
213 prepareApplicationFiles(files, modules);
214 }
215 } catch (IOException ex) {
216 throw new PluginException(ex);
217 }
218 }
219
220 private Properties releaseProperties(ResourcePool pool) throws IOException {
221 Properties props = new Properties();
222 Optional<ResourcePoolModule> javaBase = pool.moduleView().findModule("java.base");
223 javaBase.ifPresent(mod -> {
224 // fill release information available from transformed "java.base" module!
225 ModuleDescriptor desc = mod.descriptor();
226 desc.osName().ifPresent(s -> props.setProperty("OS_NAME", s));
227 desc.osVersion().ifPresent(s -> props.setProperty("OS_VERSION", s));
228 desc.osArch().ifPresent(s -> props.setProperty("OS_ARCH", s));
229 props.setProperty("JAVA_VERSION", System.getProperty("java.version"));
230 });
231
232 this.targetOsName = props.getProperty("OS_NAME");
233 if (this.targetOsName == null) {
234 throw new PluginException("TargetPlatform attribute is missing for java.base module");
235 }
236
237 Optional<ResourcePoolEntry> release = pool.findEntry("/java.base/release");
238 if (release.isPresent()) {
239 try (InputStream is = release.get().content()) {
240 props.load(is);
241 }
242 }
243
244 return props;
245 }
246
247 /**
248 * Generates launcher scripts.
249 *
250 * @param imageContent The image content.
251 * @param modules The set of modules that the runtime image contains.
252 * @throws IOException
253 */
254 protected void prepareApplicationFiles(ResourcePool imageContent, Set<String> modules) throws IOException {
|