21 * questions. |
21 * questions. |
22 */ |
22 */ |
23 |
23 |
24 /* |
24 /* |
25 * @test |
25 * @test |
26 * @bug 8001533 8004547 8035782 |
26 * @library /test/lib |
|
27 * @build FXLauncherTest jdk.test.lib.compiler.CompilerUtils |
|
28 * @bug 8001533 8004547 8035782 8202553 |
27 * @summary Test launching FX application with java -jar |
29 * @summary Test launching FX application with java -jar |
28 * Test uses main method and blank main method, a jfx app class and an incorrest |
30 * Test uses main method and blank main method, a jfx app class and an incorrect |
29 * jfx app class, a main-class for the manifest, a bogus one and none. |
31 * jfx app class, a main-class for the manifest, a bogus one and none. |
|
32 * Now that FX is no longer bundled with the JDK, this test uses a |
|
33 * "mock" javafx.graphics module to test the FX launcher. It also verifies |
|
34 * that FX is, in fact, not included with the JDK. |
30 * All should execute except the incorrect fx app class entries. |
35 * All should execute except the incorrect fx app class entries. |
31 * @run main/othervm FXLauncherTest |
36 * @run main/othervm FXLauncherTest |
32 * @key intermittent headful |
|
33 */ |
37 */ |
34 import java.io.File; |
38 import java.io.File; |
|
39 import java.nio.file.Path; |
|
40 import java.nio.file.Paths; |
35 import java.io.IOException; |
41 import java.io.IOException; |
36 import java.util.ArrayList; |
42 import java.util.ArrayList; |
|
43 import java.util.Arrays; |
37 import java.util.List; |
44 import java.util.List; |
|
45 |
|
46 import jdk.test.lib.compiler.CompilerUtils; |
38 |
47 |
39 public class FXLauncherTest extends TestHelper { |
48 public class FXLauncherTest extends TestHelper { |
40 private static final String FX_MARKER_CLASS = "javafx.application.Application"; |
49 private static final String FX_MARKER_CLASS = "javafx.application.Application"; |
41 private static void line() { |
50 private static void line() { |
42 System.out.println("_____________________________________________"); |
51 System.out.println("_____________________________________________"); |
43 } |
52 } |
44 private static File MainJavaFile = null; |
53 private static File MainJavaFile = null; |
45 private static final File FXtestJar = new File("fxtest.jar"); |
54 private static final File FXtestJar = new File("fxtest.jar"); |
46 private static final File ManifestFile = new File("manifest.txt"); |
55 private static final File ManifestFile = new File("manifest.txt"); |
47 private static final File ScratchDir = new File("."); |
56 private static final File ScratchDir = new File("."); |
|
57 |
|
58 private static final Path SRC_DIR = |
|
59 TEST_SOURCES_DIR.toPath().resolve("mockfx/src"); |
|
60 private static final Path MODS_DIR = Paths.get("mods"); |
|
61 private static final String MODULE_DIR = MODS_DIR.toString(); |
48 |
62 |
49 /* standard main class can be used as java main for fx app class */ |
63 /* standard main class can be used as java main for fx app class */ |
50 static final String StdMainClass = "helloworld.HelloWorld"; |
64 static final String StdMainClass = "helloworld.HelloWorld"; |
51 static final String ExtMainClass = "helloworld.ExtHello"; |
65 static final String ExtMainClass = "helloworld.ExtHello"; |
52 static final String NonFXMainClass = "helloworld.HelloJava"; |
66 static final String NonFXMainClass = "helloworld.HelloJava"; |
53 static int testcount = 0; |
67 static int testcount = 0; |
|
68 |
|
69 static final String LAUNCH_MODE_CLASS = "LM_CLASS"; |
|
70 static final String LAUNCH_MODE_JAR = "LM_JAR"; |
|
71 static final String LAUNCH_MODE_MODULE = "LM_MODULE"; |
54 |
72 |
55 /* a main method and a blank. */ |
73 /* a main method and a blank. */ |
56 static final String[] MAIN_METHODS = { |
74 static final String[] MAIN_METHODS = { |
57 "public static void main(String[] args) { launch(args); }", |
75 "public static void main(String[] args) { launch(args); }", |
58 " " |
76 " " |
66 try { |
84 try { |
67 String mainClass = "HelloWorld"; |
85 String mainClass = "HelloWorld"; |
68 List<String> contents = new ArrayList<>(); |
86 List<String> contents = new ArrayList<>(); |
69 contents.add("package helloworld;"); |
87 contents.add("package helloworld;"); |
70 contents.add("import javafx.application.Application;"); |
88 contents.add("import javafx.application.Application;"); |
71 contents.add("import javafx.event.ActionEvent;"); |
|
72 contents.add("import javafx.event.EventHandler;"); |
|
73 contents.add("import javafx.scene.Scene;"); |
|
74 contents.add("import javafx.scene.control.Button;"); |
|
75 contents.add("import javafx.scene.layout.StackPane;"); |
|
76 contents.add("import javafx.stage.Stage;"); |
89 contents.add("import javafx.stage.Stage;"); |
77 contents.add("public class HelloWorld extends Application {"); |
90 contents.add("public class HelloWorld extends Application {"); |
78 contents.add(mainmethod); |
91 contents.add(mainmethod); |
79 contents.add("@Override"); |
92 contents.add("@Override"); |
80 contents.add("public void start(Stage primaryStage) {"); |
93 contents.add("public void start(Stage primaryStage) {"); |
81 contents.add(" primaryStage.setTitle(\"Hello World!\");"); |
94 contents.add(" throw new InternalError(\"should never get here\");"); |
82 contents.add(" Button btn = new Button();"); |
|
83 contents.add(" btn.setText(\"Say 'Hello World'\");"); |
|
84 contents.add(" btn.setOnAction(new EventHandler<ActionEvent>() {"); |
|
85 contents.add(" @Override"); |
|
86 contents.add(" public void handle(ActionEvent event) {"); |
|
87 contents.add(" System.out.println(\"Hello World!\");"); |
|
88 contents.add(" }"); |
|
89 contents.add(" });"); |
|
90 contents.add(" StackPane root = new StackPane();"); |
|
91 contents.add(" root.getChildren().add(btn);"); |
|
92 contents.add(" primaryStage.setScene(new Scene(root, 300, 250));"); |
|
93 contents.add("// primaryStage.show(); no GUI for auto tests. "); |
|
94 contents.add(" System.out.println(\"HelloWorld.primaryStage.show();\");"); |
|
95 contents.add(" System.out.println(\"Parameters:\");" ); |
|
96 contents.add(" for(String p : getParameters().getUnnamed())"); |
|
97 contents.add(" System.out.println(\"parameter: \" + p );" ); |
|
98 contents.add(" System.exit(0);"); |
|
99 contents.add("}"); |
95 contents.add("}"); |
100 contents.add("}"); |
96 contents.add("}"); |
101 |
97 |
102 // Create and compile java source. |
98 // Create and compile java source. |
103 MainJavaFile = new File(mainClass + JAVA_FILE_EXT); |
99 MainJavaFile = new File(mainClass + JAVA_FILE_EXT); |
104 createFile(MainJavaFile, contents); |
100 createFile(MainJavaFile, contents); |
105 compile("-d", ".", mainClass + JAVA_FILE_EXT); |
101 doFxCompile("-d", ".", mainClass + JAVA_FILE_EXT); |
106 } catch (java.io.IOException ioe) { |
102 } catch (java.io.IOException ioe) { |
107 ioe.printStackTrace(); |
103 ioe.printStackTrace(); |
108 throw new RuntimeException("Failed creating HelloWorld."); |
104 throw new RuntimeException("Failed creating HelloWorld."); |
109 } |
105 } |
110 } |
106 } |
121 contents.add(mainmethod); |
117 contents.add(mainmethod); |
122 contents.add("}"); |
118 contents.add("}"); |
123 // Create and compile java source. |
119 // Create and compile java source. |
124 MainJavaFile = new File(mainClass + JAVA_FILE_EXT); |
120 MainJavaFile = new File(mainClass + JAVA_FILE_EXT); |
125 createFile(MainJavaFile, contents); |
121 createFile(MainJavaFile, contents); |
126 compile("-cp", ".", "-d", ".", mainClass + JAVA_FILE_EXT); |
122 doFxCompile("-cp", ".", "-d", ".", mainClass + JAVA_FILE_EXT); |
127 } catch (java.io.IOException ioe) { |
123 } catch (java.io.IOException ioe) { |
128 ioe.printStackTrace(); |
124 ioe.printStackTrace(); |
129 throw new RuntimeException("Failed creating ExtHello."); |
125 throw new RuntimeException("Failed creating ExtHello."); |
130 } |
126 } |
131 } |
127 } |
146 contents.add(" }"); |
142 contents.add(" }"); |
147 contents.add("}"); |
143 contents.add("}"); |
148 // Create and compile java source. |
144 // Create and compile java source. |
149 MainJavaFile = new File(mainClass + JAVA_FILE_EXT); |
145 MainJavaFile = new File(mainClass + JAVA_FILE_EXT); |
150 createFile(MainJavaFile, contents); |
146 createFile(MainJavaFile, contents); |
151 compile("-cp", ".", "-d", ".", mainClass + JAVA_FILE_EXT); |
147 doFxCompile("-cp", ".", "-d", ".", mainClass + JAVA_FILE_EXT); |
152 } catch (java.io.IOException ioe) { |
148 } catch (java.io.IOException ioe) { |
153 ioe.printStackTrace(); |
149 ioe.printStackTrace(); |
154 throw new RuntimeException("Failed creating HelloJava."); |
150 throw new RuntimeException("Failed creating HelloJava."); |
155 } |
151 } |
156 } |
152 } |
204 System.err.println(tr); |
200 System.err.println(tr); |
205 throw new Exception("Failed: " + testName + ":" + testCount); |
201 throw new Exception("Failed: " + testName + ":" + testCount); |
206 } |
202 } |
207 } |
203 } |
208 |
204 |
|
205 public static void compileFXModule() { |
|
206 final String JAVAFX_GRAPHICS_MODULE = "javafx.graphics"; |
|
207 |
|
208 try { |
|
209 // Compile mockfx/src/javafx.graphics/** into mods/javafx.graphics |
|
210 boolean compiled |
|
211 = CompilerUtils.compile(SRC_DIR.resolve(JAVAFX_GRAPHICS_MODULE), |
|
212 MODS_DIR.resolve(JAVAFX_GRAPHICS_MODULE)); |
|
213 |
|
214 if (!compiled) { |
|
215 throw new RuntimeException("Error compiling mock javafx.graphics module"); |
|
216 } |
|
217 } catch (IOException ioe) { |
|
218 throw new RuntimeException(ioe); |
|
219 } |
|
220 } |
|
221 |
|
222 static void doFxCompile(String...compilerArgs) { |
|
223 compileFXModule(); |
|
224 |
|
225 List<String> fxCompilerArgs = new ArrayList<>(); |
|
226 fxCompilerArgs.add("--module-path=" + MODULE_DIR); |
|
227 fxCompilerArgs.add("--add-modules=javafx.graphics"); |
|
228 fxCompilerArgs.addAll(Arrays.asList(compilerArgs)); |
|
229 compile(fxCompilerArgs.toArray(new String[fxCompilerArgs.size()])); |
|
230 } |
|
231 |
|
232 static TestResult doFxExec(String...cmds) { |
|
233 List<String> fxCmds = new ArrayList<>(); |
|
234 fxCmds.addAll(Arrays.asList(cmds)); |
|
235 fxCmds.add(1, "--module-path=" + MODULE_DIR); |
|
236 fxCmds.add(2, "--add-modules=javafx.graphics"); |
|
237 return doExec(fxCmds.toArray(new String[fxCmds.size()])); |
|
238 } |
|
239 |
209 /* |
240 /* |
210 * Set Main-Class and iterate main_methods. |
241 * Set Main-Class and iterate main_methods. |
211 * Try launching with both -jar and -cp methods, with and without FX main |
242 * Try launching with both -jar and -cp methods, with and without FX main |
212 * class manifest entry. |
243 * class manifest entry. |
213 * All cases should run. |
244 * All cases should run. |
238 System.out.println("test# " + testcount + "- Main method: " + mm); |
269 System.out.println("test# " + testcount + "- Main method: " + mm); |
239 createJavaFile(mm); |
270 createJavaFile(mm); |
240 createFile(ManifestFile, createManifestContents(StdMainClass, fxMC)); |
271 createFile(ManifestFile, createManifestContents(StdMainClass, fxMC)); |
241 createJar(FXtestJar, ManifestFile); |
272 createJar(FXtestJar, ManifestFile); |
242 String sTestJar = FXtestJar.getAbsolutePath(); |
273 String sTestJar = FXtestJar.getAbsolutePath(); |
|
274 String launchMode; |
243 final TestResult tr; |
275 final TestResult tr; |
244 if (useCP) { |
276 if (useCP) { |
245 tr = doExec(javaCmd, "-cp", sTestJar, StdMainClass, APP_PARMS[0], APP_PARMS[1]); |
277 tr = doFxExec(javaCmd, "-cp", sTestJar, StdMainClass, APP_PARMS[0], APP_PARMS[1]); |
|
278 launchMode = LAUNCH_MODE_CLASS; |
246 } else { |
279 } else { |
247 tr = doExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]); |
280 tr = doFxExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]); |
|
281 launchMode = LAUNCH_MODE_JAR; |
248 } |
282 } |
249 tr.checkPositive(); |
283 tr.checkPositive(); |
250 if (tr.testStatus && tr.contains("HelloWorld.primaryStage.show()")) { |
284 if (tr.testStatus) { |
|
285 if (!tr.contains(launchMode)) { |
|
286 System.err.println("ERROR: Did not find " |
|
287 + launchMode + " in output!"); |
|
288 } |
251 for (String p : APP_PARMS) { |
289 for (String p : APP_PARMS) { |
252 if (!tr.contains(p)) { |
290 if (!tr.contains(p)) { |
253 System.err.println("ERROR: Did not find " |
291 System.err.println("ERROR: Did not find " |
254 + p + " in output!"); |
292 + p + " in output!"); |
255 } |
293 } |
289 createJavaFile(mm); |
327 createJavaFile(mm); |
290 createExtJavaFile(mm); |
328 createExtJavaFile(mm); |
291 createFile(ManifestFile, createManifestContents(ExtMainClass, fxMC)); |
329 createFile(ManifestFile, createManifestContents(ExtMainClass, fxMC)); |
292 createJar(FXtestJar, ManifestFile); |
330 createJar(FXtestJar, ManifestFile); |
293 String sTestJar = FXtestJar.getAbsolutePath(); |
331 String sTestJar = FXtestJar.getAbsolutePath(); |
|
332 String launchMode; |
294 final TestResult tr; |
333 final TestResult tr; |
295 if (useCP) { |
334 if (useCP) { |
296 tr = doExec(javaCmd, "-cp", sTestJar, ExtMainClass, APP_PARMS[0], APP_PARMS[1]); |
335 tr = doFxExec(javaCmd, "-cp", sTestJar, ExtMainClass, APP_PARMS[0], APP_PARMS[1]); |
|
336 launchMode = LAUNCH_MODE_CLASS; |
297 } else { |
337 } else { |
298 tr = doExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]); |
338 tr = doFxExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]); |
|
339 launchMode = LAUNCH_MODE_JAR; |
299 } |
340 } |
300 tr.checkPositive(); |
341 tr.checkPositive(); |
301 if (tr.testStatus && tr.contains("HelloWorld.primaryStage.show()")) { |
342 if (tr.testStatus) { |
|
343 if (!tr.contains(launchMode)) { |
|
344 System.err.println("ERROR: Did not find " |
|
345 + launchMode + " in output!"); |
|
346 } |
302 for (String p : APP_PARMS) { |
347 for (String p : APP_PARMS) { |
303 if (!tr.contains(p)) { |
348 if (!tr.contains(p)) { |
304 System.err.println("ERROR: Did not find " |
349 System.err.println("ERROR: Did not find " |
305 + p + " in output!"); |
350 + p + " in output!"); |
306 } |
351 } |
321 System.out.println("test# " + testcount + ": abort on missing Main-Class"); |
366 System.out.println("test# " + testcount + ": abort on missing Main-Class"); |
322 createJavaFile(" "); // no main() needed |
367 createJavaFile(" "); // no main() needed |
323 createFile(ManifestFile, createManifestContents(null, StdMainClass)); // No MC, but supply JAC |
368 createFile(ManifestFile, createManifestContents(null, StdMainClass)); // No MC, but supply JAC |
324 createJar(FXtestJar, ManifestFile); |
369 createJar(FXtestJar, ManifestFile); |
325 String sTestJar = FXtestJar.getAbsolutePath(); |
370 String sTestJar = FXtestJar.getAbsolutePath(); |
326 TestResult tr = doExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]); |
371 TestResult tr = doFxExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]); |
327 tr.checkNegative(); // should abort if no Main-Class |
372 tr.checkNegative(); // should abort if no Main-Class |
328 if (tr.testStatus) { |
373 if (tr.testStatus) { |
329 if (!tr.contains("no main manifest attribute")) { |
374 if (!tr.contains("no main manifest attribute")) { |
330 System.err.println("ERROR: launcher did not abort properly"); |
375 System.err.println("ERROR: launcher did not abort properly"); |
331 } |
376 } |
361 createJar(FXtestJar, ManifestFile); |
406 createJar(FXtestJar, ManifestFile); |
362 String sTestJar = FXtestJar.getAbsolutePath(); |
407 String sTestJar = FXtestJar.getAbsolutePath(); |
363 final TestResult tr; |
408 final TestResult tr; |
364 |
409 |
365 if (useCP) { |
410 if (useCP) { |
366 tr = doExec(javaCmd, "-verbose:class", "-cp", sTestJar, NonFXMainClass, APP_PARMS[0], APP_PARMS[1]); |
411 tr = doFxExec(javaCmd, "-verbose:class", "-cp", sTestJar, NonFXMainClass, APP_PARMS[0], APP_PARMS[1]); |
367 } else { |
412 } else { |
368 tr = doExec(javaCmd, "-verbose:class", "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]); |
413 tr = doFxExec(javaCmd, "-verbose:class", "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]); |
369 } |
414 } |
370 tr.checkPositive(); |
415 tr.checkPositive(); |
371 if (tr.testStatus) { |
416 if (tr.testStatus) { |
372 if (!tr.notContains("jfxrt.jar")) { |
417 if (!tr.notContains("jfxrt.jar")) { |
373 System.out.println("testing for extraneous jfxrt jar"); |
418 System.out.println("testing for extraneous jfxrt jar"); |
388 } |
433 } |
389 checkStatus(tr, testname, testcount, NonFXMainClass); |
434 checkStatus(tr, testname, testcount, NonFXMainClass); |
390 } |
435 } |
391 |
436 |
392 public static void main(String... args) throws Exception { |
437 public static void main(String... args) throws Exception { |
393 //check if fx is part of jdk |
438 |
|
439 // Ensure that FX is not part of jdk |
394 Class<?> fxClass = null; |
440 Class<?> fxClass = null; |
395 try { |
441 try { |
396 fxClass = Class.forName(FX_MARKER_CLASS); |
442 fxClass = Class.forName(FX_MARKER_CLASS); |
397 } catch (ClassNotFoundException ex) { |
443 } catch (ClassNotFoundException ex) { |
398 // do nothing |
444 // do nothing |
399 } |
445 } |
400 if (fxClass != null) { |
446 if (fxClass != null) { |
401 FXLauncherTest fxt = new FXLauncherTest(); |
447 throw new RuntimeException("JavaFX modules erroneously included in the JDK"); |
402 fxt.run(args); |
448 } |
403 if (testExitValue > 0) { |
449 |
404 System.out.println("Total of " + testExitValue |
450 FXLauncherTest fxt = new FXLauncherTest(); |
405 + " failed. Test cases covered: " |
451 fxt.run(args); |
406 + FXLauncherTest.testcount); |
452 if (testExitValue > 0) { |
407 System.exit(1); |
453 System.out.println("Total of " + testExitValue |
408 } else { |
454 + " failed. Test cases covered: " |
409 System.out.println("All tests pass. Test cases covered: " |
455 + FXLauncherTest.testcount); |
410 + FXLauncherTest.testcount); |
456 System.exit(1); |
411 } |
|
412 } else { |
457 } else { |
413 System.err.println("Warning: JavaFX components missing or not supported"); |
458 System.out.println("All tests pass. Test cases covered: " |
414 System.err.println(" test passes vacuously."); |
459 + FXLauncherTest.testcount); |
415 } |
460 } |
416 } |
461 } |
|
462 |
417 } |
463 } |