192
193 scripts.add(new Script[]{script});
194 }
195 }
196 }
197 }
198 return scripts;
199 }
200
201 @Test
202 public void test() throws IOException {
203 if (script.jarMainClass == SetWrong) {
204 initJarWithWrongMainClass();
205 }
206
207 if (script.expectedErrorMessage != null) {
208 // This is the case when main class is not found nor in jar
209 // file nor on command line.
210 List<String> output = cmd
211 .saveConsoleOutput(true)
212 .execute()
213 .assertExitCodeIs(1)
214 .getOutput();
215 TKit.assertTextStream(script.expectedErrorMessage).apply(output.stream());
216 return;
217 }
218
219 // Get here only if main class is specified.
220 boolean appShouldSucceed = false;
221
222 // Should succeed if valid main class is set on the command line.
223 appShouldSucceed |= (script.mainClass == SetRight);
224
225 // Should succeed if main class is not set on the command line but set
226 // to valid value in the jar.
227 appShouldSucceed |= (script.mainClass == NotSet && script.jarMainClass == SetRight);
228
229 if (appShouldSucceed) {
230 cmd.executeAndAssertHelloAppImageCreated();
231 } else {
232 cmd.executeAndAssertImageCreated();
233 if (!cmd.isFakeRuntime(String.format("Not running [%s]",
234 cmd.appLauncherPath()))) {
235 List<String> output = new Executor()
236 .setDirectory(cmd.outputDir())
237 .setExecutable(cmd.appLauncherPath())
238 .dumpOutput().saveOutput()
239 .execute().assertExitCodeIs(1).getOutput();
240 TKit.assertTextStream(String.format(
241 "Error: Could not find or load main class %s",
242 nonExistingMainClass)).apply(output.stream());
243 }
244 }
245 }
246
247 private void initJarWithWrongMainClass() throws IOException {
248 // Call JPackageCommand.executePrerequisiteActions() to build app's jar.
249 // executePrerequisiteActions() is called by JPackageCommand instance
250 // only once.
251 cmd.executePrerequisiteActions();
252
253 final Path jarFile;
254 if (script.appDesc.moduleName() != null) {
255 jarFile = Path.of(cmd.getArgumentValue("--module-path"),
256 script.appDesc.jarFileName());
257 } else {
258 jarFile = cmd.inputDir().resolve(cmd.getArgumentValue("--main-jar"));
259 }
272
273 // Extract new jar but skip app's class.
274 explodeJar(jarFile, workDir,
275 jarEntry -> !Path.of(jarEntry.getName()).equals(
276 badAppDesc.classFilePath()));
277
278 // At this point we should have:
279 // 1. Manifest from the new jar referencing non-existing class
280 // as the main class.
281 // 2. Module descriptor referencing non-existing class as the main
282 // class in case of modular app.
283 // 3. App's class from the old jar. We need it to let jlink find some
284 // classes in the package declared in module descriptor
285 // in case of modular app.
286
287 Files.delete(jarFile);
288 new Executor().setToolProvider(JavaTool.JAR)
289 .addArguments("-v", "-c", "-M", "-f", jarFile.toString())
290 .addArguments("-C", workDir.toString(), ".")
291 .dumpOutput()
292 .execute().assertExitCodeIsZero();
293 });
294 }
295
296 private static void explodeJar(Path jarFile, Path workDir,
297 Predicate<JarEntry> filter) throws IOException {
298 try (var jar = new JarFile(jarFile.toFile())) {
299 jar.stream()
300 .filter(Predicate.not(JarEntry::isDirectory))
301 .filter(filter)
302 .sequential().forEachOrdered(ThrowingConsumer.toConsumer(
303 jarEntry -> {
304 try (var in = jar.getInputStream(jarEntry)) {
305 Path fileName = workDir.resolve(jarEntry.getName());
306 Files.createDirectories(fileName.getParent());
307 Files.copy(in, fileName);
308 }
309 }));
310 }
311 }
312
|
192
193 scripts.add(new Script[]{script});
194 }
195 }
196 }
197 }
198 return scripts;
199 }
200
201 @Test
202 public void test() throws IOException {
203 if (script.jarMainClass == SetWrong) {
204 initJarWithWrongMainClass();
205 }
206
207 if (script.expectedErrorMessage != null) {
208 // This is the case when main class is not found nor in jar
209 // file nor on command line.
210 List<String> output = cmd
211 .saveConsoleOutput(true)
212 .execute(1)
213 .getOutput();
214 TKit.assertTextStream(script.expectedErrorMessage).apply(output.stream());
215 return;
216 }
217
218 // Get here only if main class is specified.
219 boolean appShouldSucceed = false;
220
221 // Should succeed if valid main class is set on the command line.
222 appShouldSucceed |= (script.mainClass == SetRight);
223
224 // Should succeed if main class is not set on the command line but set
225 // to valid value in the jar.
226 appShouldSucceed |= (script.mainClass == NotSet && script.jarMainClass == SetRight);
227
228 if (appShouldSucceed) {
229 cmd.executeAndAssertHelloAppImageCreated();
230 } else {
231 cmd.executeAndAssertImageCreated();
232 if (!cmd.isFakeRuntime(String.format("Not running [%s]",
233 cmd.appLauncherPath()))) {
234 List<String> output = new Executor()
235 .setDirectory(cmd.outputDir())
236 .setExecutable(cmd.appLauncherPath())
237 .dumpOutput().saveOutput()
238 .execute(1).getOutput();
239 TKit.assertTextStream(String.format(
240 "Error: Could not find or load main class %s",
241 nonExistingMainClass)).apply(output.stream());
242 }
243 }
244 }
245
246 private void initJarWithWrongMainClass() throws IOException {
247 // Call JPackageCommand.executePrerequisiteActions() to build app's jar.
248 // executePrerequisiteActions() is called by JPackageCommand instance
249 // only once.
250 cmd.executePrerequisiteActions();
251
252 final Path jarFile;
253 if (script.appDesc.moduleName() != null) {
254 jarFile = Path.of(cmd.getArgumentValue("--module-path"),
255 script.appDesc.jarFileName());
256 } else {
257 jarFile = cmd.inputDir().resolve(cmd.getArgumentValue("--main-jar"));
258 }
271
272 // Extract new jar but skip app's class.
273 explodeJar(jarFile, workDir,
274 jarEntry -> !Path.of(jarEntry.getName()).equals(
275 badAppDesc.classFilePath()));
276
277 // At this point we should have:
278 // 1. Manifest from the new jar referencing non-existing class
279 // as the main class.
280 // 2. Module descriptor referencing non-existing class as the main
281 // class in case of modular app.
282 // 3. App's class from the old jar. We need it to let jlink find some
283 // classes in the package declared in module descriptor
284 // in case of modular app.
285
286 Files.delete(jarFile);
287 new Executor().setToolProvider(JavaTool.JAR)
288 .addArguments("-v", "-c", "-M", "-f", jarFile.toString())
289 .addArguments("-C", workDir.toString(), ".")
290 .dumpOutput()
291 .execute();
292 });
293 }
294
295 private static void explodeJar(Path jarFile, Path workDir,
296 Predicate<JarEntry> filter) throws IOException {
297 try (var jar = new JarFile(jarFile.toFile())) {
298 jar.stream()
299 .filter(Predicate.not(JarEntry::isDirectory))
300 .filter(filter)
301 .sequential().forEachOrdered(ThrowingConsumer.toConsumer(
302 jarEntry -> {
303 try (var in = jar.getInputStream(jarEntry)) {
304 Path fileName = workDir.resolve(jarEntry.getName());
305 Files.createDirectories(fileName.getParent());
306 Files.copy(in, fileName);
307 }
308 }));
309 }
310 }
311
|