1 /* 2 * Copyright (c) 2011, 2014, 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 26 package com.sun.javafx.tools.packager; 27 28 import com.sun.javafx.tools.resource.PackagerResource; 29 import java.io.File; 30 import java.io.FileInputStream; 31 import java.io.FileOutputStream; 32 import java.io.FileWriter; 33 import java.io.IOException; 34 import java.util.Base64; 35 import java.util.Date; 36 import java.util.HashMap; 37 import java.util.ArrayList; 38 import java.util.jar.Attributes; 39 import java.util.jar.JarEntry; 40 import java.util.jar.JarFile; 41 import java.util.jar.JarOutputStream; 42 import java.util.jar.Manifest; 43 import java.util.zip.ZipEntry; 44 import java.util.zip.ZipInputStream; 45 import javax.xml.parsers.DocumentBuilder; 46 import javax.xml.parsers.DocumentBuilderFactory; 47 import javax.xml.parsers.ParserConfigurationException; 48 49 import static org.junit.Assert.*; 50 import org.junit.Before; 51 import org.junit.BeforeClass; 52 import org.junit.Ignore; 53 import org.junit.Rule; 54 import org.junit.Test; 55 import org.junit.rules.TemporaryFolder; 56 import org.w3c.dom.Document; 57 import org.xml.sax.ErrorHandler; 58 import org.xml.sax.SAXException; 59 import org.xml.sax.SAXParseException; 60 61 public class PackagerLibTest { 62 63 @Rule 64 public TemporaryFolder dest = new TemporaryFolder(); 65 @Rule 66 public TemporaryFolder src = new TemporaryFolder(); 67 static boolean retain = false; 68 File srcRoot; 69 File destRoot; 70 71 private PackagerLib lib; 72 73 @BeforeClass 74 public static void prepareApp() { 75 retain = Boolean.parseBoolean(System.getProperty("RETAIN_PACKAGER_TESTS")); 76 System.out.println(retain?"Retain apps" : "destroy apps"); 77 } 78 79 @Before 80 public void setUp() { 81 lib = new PackagerLib(); 82 if (retain) { 83 srcRoot = new File("build/tmp/tests/packagerlib/src"); 84 destRoot = new File("build/tmp/tests/packagerlib/dest"); 85 srcRoot.mkdirs(); 86 destRoot.mkdirs(); 87 } else { 88 srcRoot = src.getRoot(); 89 destRoot = dest.getRoot(); 90 } 91 System.out.println("src " + srcRoot); 92 System.out.println("dest " + destRoot); 93 } 94 95 @Test(expected=IllegalArgumentException.class) 96 public void testPackageAsJar_null() throws PackagerException { 97 lib.packageAsJar(null); 98 } 99 100 private CreateJarParams defaultParams() { 101 CreateJarParams params = new CreateJarParams(); 102 params.outdir = dest.getRoot(); 103 params.outfile = "temp"; 104 params.embedLauncher = false; 105 params.css2bin = false; 106 params.applicationClass = DUMMY_APP_MAIN; 107 108 return params; 109 } 110 111 @Test 112 public void testPackageAsJar_jarCreate() throws PackagerException { 113 lib.packageAsJar(defaultParams()); 114 115 File testFile = new File(dest.getRoot(), "temp.jar"); 116 assertTrue(testFile.exists() && testFile.canRead()); 117 } 118 119 @Test 120 public void testPackageAsJar_jarCreate2() throws PackagerException { 121 lib.packageAsJar(defaultParams()); 122 123 File testFile = new File(dest.getRoot(), "temp.jar"); 124 assertTrue(testFile.exists() && testFile.canRead()); 125 } 126 127 // longer than 56 characters (see RT-26553) 128 final private static String LONG_ARG_VALUE = "VERYLONGSTRINGVERYLONGSTRINGVERYLONGSTRINGVERYLONGST" + 129 "RINGVERYLONGSTRINGVERYLONGSTRINGVERYLONGSTRINGVERYLO" + 130 "NGSTRINGVERYLONGSTRINGVERYLONGSTRINGVERYLONGSTRINGVE" + 131 "RYLONGSTRINGVERYLONGSTRING"; 132 133 @Test 134 public void testPackageAsJar_longArgValue() throws PackagerException, IOException { 135 CreateJarParams params = defaultParams(); 136 params.manifestAttrs = new HashMap<>(); 137 params.arguments = new ArrayList<>(); 138 139 // added to manifest as JavaFX-Argument-1 140 // note that this value will be base64 encoded 141 params.arguments.add(LONG_ARG_VALUE); 142 lib.packageAsJar(params); 143 144 File testFile = new File(dest.getRoot(), "temp.jar"); 145 JarFile jar = new JarFile(testFile); 146 Manifest m = jar.getManifest(); 147 148 String argValue = m.getMainAttributes().getValue("JavaFX-Argument-1"); 149 assertEquals(LONG_ARG_VALUE, new String(Base64.getDecoder().decode(argValue))); 150 } 151 152 @Test 153 @Ignore 154 public void testPackageAsJar_manifest() throws PackagerException, IOException { 155 CreateJarParams params = defaultParams(); 156 params.manifestAttrs = new HashMap<>(); 157 params.manifestAttrs.put("testfoo", "bar"); 158 params.applicationClass = "ham.eggs.Vikings"; 159 lib.packageAsJar(params); 160 161 File testFile = new File(dest.getRoot(), "temp.jar"); 162 JarFile jar = new JarFile(testFile); 163 Manifest m = jar.getManifest(); 164 assertEquals(4, m.getMainAttributes().size()); 165 assertEquals("1.0", 166 m.getMainAttributes().get(Attributes.Name.MANIFEST_VERSION)); 167 assertEquals("ham.eggs.Vikings", 168 m.getMainAttributes().get(Attributes.Name.MAIN_CLASS)); 169 assertEquals("JavaFX Packager", 170 m.getMainAttributes().getValue("Created-By")); 171 assertEquals("bar", m.getMainAttributes().getValue("testfoo")); 172 } 173 174 175 @Test 176 @Ignore // requires jfxrt.jar on classpath 177 public void testPackageAsJar_css2bss() throws PackagerException, IOException { 178 CreateJarParams params = defaultParams(); 179 params.resources.add(new PackagerResource(src.getRoot(), ".")); 180 File css = src.newFile("hello.css"); 181 new FileWriter(css).write(" .hello { -fx-color: red; }"); 182 lib.packageAsJar(params); 183 184 File testFile = new File(dest.getRoot(), "temp.jar"); 185 JarFile jar = new JarFile(testFile); 186 187 // NOTE: Test is incomplete. 188 } 189 190 @Test 191 @Ignore 192 public void testPackageAsJar_embedLauncher() throws PackagerException, IOException { 193 CreateJarParams params = defaultParams(); 194 params.applicationClass = "FooBar"; 195 params.embedLauncher = true; 196 params.fxVersion = "2.0"; 197 params.resources.add(new PackagerResource(src.getRoot(), ".")); 198 lib.packageAsJar(params); 199 200 File testFile = new File(dest.getRoot(), "temp.jar"); 201 JarFile jar = new JarFile(testFile); 202 Manifest m = jar.getManifest(); 203 assertEquals("1.0", 204 m.getMainAttributes().get(Attributes.Name.MANIFEST_VERSION)); 205 assertEquals("com/javafx/main/Main", 206 m.getMainAttributes().get(Attributes.Name.MAIN_CLASS)); 207 assertEquals("FooBar", 208 m.getMainAttributes().getValue("JavaFX-Application-Class")); 209 assertEquals("2.0", m.getMainAttributes().getValue("JavaFX-Version")); 210 assertEquals(null, m.getMainAttributes().getValue("JavaFX-Preloader-Class")); 211 assertEquals(null, m.getMainAttributes().getValue("JavaFX-Class-Path")); 212 assertEquals(null, m.getMainAttributes().getValue("JavaFX-Fallback-Class")); 213 } 214 215 @Test 216 public void testPackageAsJar_embedLauncher2() throws PackagerException, IOException { 217 CreateJarParams params = defaultParams(); 218 params.applicationClass = "FooBar"; 219 params.preloader = "PreLoader"; 220 params.fxVersion = "2.0"; 221 params.embedLauncher = true; 222 params.resources.add(new PackagerResource(src.getRoot(), ".")); 223 lib.packageAsJar(params); 224 225 File testFile = new File(dest.getRoot(), "temp.jar"); 226 JarFile jar = new JarFile(testFile); 227 Manifest m = jar.getManifest(); 228 assertEquals("PreLoader", 229 m.getMainAttributes().getValue("JavaFX-Preloader-Class")); 230 } 231 232 @Test 233 @Ignore 234 public void testPackageAsJar_embedLauncher3() throws PackagerException, IOException { 235 CreateJarParams params = defaultParams(); 236 params.applicationClass = "FooBar"; 237 params.classpath = "/a/b/c;d/e/f/"; 238 params.fxVersion = "2.0"; 239 params.embedLauncher = true; 240 params.resources.add(new PackagerResource(src.getRoot(), ".")); 241 lib.packageAsJar(params); 242 243 File testFile = new File(dest.getRoot(), "temp.jar"); 244 JarFile jar = new JarFile(testFile); 245 Manifest m = jar.getManifest(); 246 assertEquals("/a/b/c d/e/f/", 247 m.getMainAttributes().getValue("JavaFX-Class-Path")); 248 } 249 250 @Test 251 @Ignore 252 public void testPackageAsJar_embedLauncher4() throws PackagerException, IOException { 253 CreateJarParams params = defaultParams(); 254 params.applicationClass = "FooBar"; 255 params.preloader = "PreLoader"; 256 params.fallbackClass = "com.sun.Fallback"; 257 params.fxVersion = "2.0"; 258 params.embedLauncher = true; 259 params.resources.add(new PackagerResource(src.getRoot(), ".")); 260 lib.packageAsJar(params); 261 262 File testFile = new File(dest.getRoot(), "temp.jar"); 263 JarFile jar = new JarFile(testFile); 264 Manifest m = jar.getManifest(); 265 assertEquals("com.sun.Fallback", 266 m.getMainAttributes().getValue("JavaFX-Fallback-Class")); 267 } 268 269 // Right now we only validate that XML is well formed. We should validate against schema 270 private void validateJNLP(File file) { 271 try { 272 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 273 factory.setValidating(false); 274 factory.setNamespaceAware(true); 275 276 DocumentBuilder builder = factory.newDocumentBuilder(); 277 278 builder.setErrorHandler(new SimpleErrorHandler()); 279 try { 280 Document document = builder.parse(file); 281 } catch (SAXException ex) { 282 fail("Parsing exception: "+ex); 283 } catch (IOException ex) { 284 fail("IOException: "+ex); 285 } 286 } catch (ParserConfigurationException ex) { 287 fail("Runtime issue: "+ex); 288 } 289 } 290 291 @Test 292 public void testGenerateDeploymentPackages() throws PackagerException, IOException { 293 DeployParams params = new DeployParams(); 294 params.outdir = destRoot; 295 params.outfile = "temp"; 296 params.setApplicationClass(DUMMY_APP_MAIN); 297 File j1 = createTestJar(null, DUMMY_APP_MAIN); 298 params.addResource(j1.getParentFile(), j1); 299 300 lib.generateDeploymentPackages(params); 301 302 File jnlpFile = new File(destRoot, "temp.jnlp"); 303 File htmlFile = new File(destRoot, "temp.html"); 304 assertTrue(jnlpFile.exists() && jnlpFile.canRead()); 305 assertTrue(htmlFile.exists() && htmlFile.canRead()); 306 307 validateJNLP(jnlpFile); 308 309 // 310 } 311 312 @Test 313 //extension JNLP with 1 jar 314 public void testGenerateExtensionJNLP_basic() throws PackagerException, IOException { 315 DeployParams params = new DeployParams(); 316 params.outdir = destRoot; 317 params.outfile = "temp"; 318 params.isExtension = true; 319 params.setApplicationClass(DUMMY_APP_MAIN); 320 File j1 = createTestJar(null, DUMMY_APP_MAIN); 321 params.addResource(j1.getParentFile(), j1); 322 323 lib.generateDeploymentPackages(params); 324 325 File jnlpFile = new File(destRoot, "temp.jnlp"); 326 assertTrue(jnlpFile.exists() && jnlpFile.canRead()); 327 328 validateJNLP(jnlpFile); 329 } 330 331 @Test 332 //extension JNLP with 2 jars 333 public void testGenerateExtensionJNLP_multi() throws PackagerException, IOException { 334 DeployParams params = new DeployParams(); 335 params.outdir = destRoot; 336 params.outfile = "temp"; 337 params.isExtension = true; 338 params.setApplicationClass(DUMMY_APP_MAIN); 339 File j1 = createTestJar(null, DUMMY_APP_MAIN); 340 File j2 = createTestJar(null, DUMMY_APP_MAIN); 341 params.addResource(j1.getParentFile(), j1); 342 params.addResource(j2.getParentFile(), j2); 343 344 lib.generateDeploymentPackages(params); 345 346 File jnlpFile = new File(destRoot, "temp.jnlp"); 347 assertTrue(jnlpFile.exists() && jnlpFile.canRead()); 348 349 validateJNLP(jnlpFile); 350 } 351 352 @Test 353 //extension JNLP with several jars. jars may be platform specific 354 public void testGenerateExtensionJNLP_multi_mix() throws PackagerException, IOException { 355 DeployParams params = new DeployParams(); 356 params.outdir = destRoot; 357 params.outfile = "temp"; 358 params.isExtension = true; 359 params.setApplicationClass(DUMMY_APP_MAIN); 360 File j1 = createTestJar(null, DUMMY_APP_MAIN); 361 File j2 = createTestJar(null, DUMMY_APP_MAIN); 362 File j3 = createTestJar(null, DUMMY_APP_MAIN); 363 params.addResource(j1.getParentFile(), j1, "eager", null, "win", null); 364 params.addResource(j2.getParentFile(), j2); 365 params.addResource(j2.getParentFile(), j3, "eager", null, "win", null); 366 params.addResource(j2.getParentFile(), j3, "eager", null, "linux", null); 367 368 lib.generateDeploymentPackages(params); 369 370 File jnlpFile = new File(destRoot, "temp.jnlp"); 371 assertTrue(jnlpFile.exists() && jnlpFile.canRead()); 372 373 validateJNLP(jnlpFile); 374 } 375 376 void validateSignedJar(File jar) throws IOException { 377 assertTrue("Expect to be able to read signed jar", jar.canRead()); 378 379 ZipInputStream jis = new ZipInputStream(new FileInputStream(jar)); 380 381 ZipEntry ze; 382 while ((ze = jis.getNextEntry()) != null) { 383 if ("META-INF/SIGNATURE.BSF".equalsIgnoreCase(ze.getName())) { 384 //found signatures 385 return; 386 } 387 } 388 389 fail("Failed to find signatures in the jar"); 390 } 391 392 public void doTestSignJar(Manifest m) throws PackagerException, IOException { 393 File inputJar = createTestJar(m, "DUMMY.class"); 394 395 SignJarParams params = new SignJarParams(); 396 params.setKeyStore(new File("test.keystore")); 397 params.setStorePass("xyz123"); 398 params.setAlias("TestAlias"); 399 params.addResource(inputJar.getParentFile(), inputJar); 400 401 File out = dest.getRoot(); 402 403 params.setOutdir(out); 404 405 lib.signJar(params); 406 407 validateSignedJar(new File(out, inputJar.getName())); 408 } 409 410 411 @Test 412 @Ignore 413 public void testSignJar_basic() throws PackagerException, IOException { 414 doTestSignJar(new Manifest()); 415 } 416 417 @Test 418 @Ignore 419 public void testSignJar_noManifest() throws PackagerException, IOException { 420 doTestSignJar(null); 421 } 422 423 @Ignore 424 @Test 425 public void testSignJar_alreadySigned() throws PackagerException, IOException { 426 //TODO: implement creating signed test jar (using normal sign method) 427 doTestSignJar(new Manifest()); 428 } 429 430 private File createTestJar(Manifest m, String entryName) throws IOException { 431 File res = File.createTempFile("test", ".jar"); 432 res.delete(); 433 434 if (m != null) { 435 //ensure version is there or manifest can be ignored ... 436 m.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); 437 } 438 439 JarOutputStream jos = (m == null) ? 440 new JarOutputStream(new FileOutputStream(res)) : 441 new JarOutputStream(new FileOutputStream(res), m); 442 443 byte content[] = "Dummy content".getBytes(); 444 JarEntry entry = new JarEntry(entryName); 445 entry.setTime(new Date().getTime()); 446 jos.putNextEntry(entry); 447 jos.write(content, 0, content.length); 448 jos.closeEntry(); 449 450 jos.close(); 451 452 return res; 453 } 454 455 final private static String DUMMY_APP_MAIN = "DummyLauncherClass"; 456 457 private void doTest_existingJar(Manifest inputManifest, CreateJarParams params) 458 throws PackagerException, IOException { 459 String dummyJarEntryName = DUMMY_APP_MAIN; 460 File inputJar = createTestJar(inputManifest, dummyJarEntryName); 461 462 if (params == null) { 463 params = defaultParams(); 464 } 465 466 //common settings 467 params.outdir = dest.getRoot(); 468 params.embedLauncher = true; 469 params.resources.add( 470 new PackagerResource(inputJar.getParentFile(), inputJar)); 471 472 lib.packageAsJar(params); 473 474 File testFile = new File(dest.getRoot(), "temp.jar"); 475 assertTrue(testFile.exists() && testFile.canRead()); 476 477 try (JarFile jar = new JarFile(testFile)) { 478 JarEntry je = jar.getJarEntry(dummyJarEntryName); 479 assertNotNull("Expect old jar content to be copied.", je); 480 481 Manifest m = jar.getManifest(); 482 assertNotNull("Manifest should not be null", m); 483 484 Attributes attrs = m.getMainAttributes(); 485 assertNotNull("Expect not null main attributes", attrs); 486 487 assertEquals("Manifest version is not 1.0", 488 "1.0", attrs.get(Attributes.Name.MANIFEST_VERSION)); 489 assertEquals("Main class should point to JavaFX launcher", 490 "com/javafx/main/Main", attrs.get(Attributes.Name.MAIN_CLASS)); 491 assertNotNull("JavaFX version should be specified", 492 attrs.getValue("JavaFX-Version")); 493 assertNull("ClassPath entry should be reset", 494 attrs.getValue(Attributes.Name.CLASS_PATH)); 495 496 assertEquals("Unexpected app main", 497 DUMMY_APP_MAIN, attrs.getValue("JavaFX-Application-Class")); 498 499 assertEquals("Preloader value should match", 500 params.preloader, attrs.getValue("JavaFX-Preloader-Class")); 501 assertEquals("Fallback class value should match", 502 params.preloader, attrs.getValue("JavaFX-Fallback-Class")); 503 504 String mainClass = attrs.getValue("JavaFX-Application-Class"); 505 assertNotNull("JavaFX Main class must be present", mainClass); 506 assertEquals("Expect main class to be the same as requested", 507 params.applicationClass, mainClass); 508 509 //classpath should be based 510 String inputClasspath = null; 511 if (inputManifest != null && inputManifest.getMainAttributes() != null) { 512 inputClasspath = inputManifest.getMainAttributes().getValue( 513 Attributes.Name.CLASS_PATH); 514 } 515 String resultClassPath = attrs.getValue("JavaFX-Class-Path"); 516 517 if (params.classpath == null) { 518 assertEquals("Expect input classpath copied", 519 inputClasspath, resultClassPath); 520 } else { 521 assertEquals("Expect classpath to be set as in ant task", 522 params.classpath, resultClassPath); 523 } 524 525 //check that custom entries from input manifest were preserved 526 if (inputManifest != null) { 527 for (Object k : inputManifest.getMainAttributes().keySet()) { 528 if (k instanceof String && ((String) k).contains("Test")) { 529 assertEquals("Expect main manifest atttribute to be copied", 530 inputManifest.getMainAttributes().getValue((String) k), 531 attrs.getValue((String) k)); 532 } 533 } 534 } 535 536 } 537 //TODO: validate that manifest entries for jar enttries are copied 538 } 539 540 @Test 541 @Ignore 542 public void testPackageAsJar_existingJar_noManifestJar() 543 throws PackagerException, IOException { 544 CreateJarParams params = defaultParams(); 545 params.applicationClass = DUMMY_APP_MAIN; 546 doTest_existingJar(null, params); 547 } 548 549 @Test 550 @Ignore 551 public void testPackageAsJar_existingJar_ExecutableJar_Overriden() 552 throws PackagerException, IOException { 553 CreateJarParams params = defaultParams(); 554 params.classpath = "c.jar"; 555 Manifest m = new Manifest(); 556 Attributes attr = m.getMainAttributes(); 557 attr.put(Attributes.Name.MAIN_CLASS, "SomethingElse"); 558 attr.put(Attributes.Name.CLASS_PATH, "a.jar:b.jar"); 559 560 //expect explicit parameters to overwrite given 561 doTest_existingJar(m, params); 562 } 563 564 @Test 565 @Ignore 566 public void testPackageAsJar_existingJar_ExecutableJar() 567 throws PackagerException, IOException { 568 System.err.println("Marker!"); 569 CreateJarParams params = defaultParams(); 570 params.applicationClass = null; //reset 571 Manifest m = new Manifest(); 572 Attributes attr = m.getMainAttributes(); 573 attr.put(Attributes.Name.MAIN_CLASS, DUMMY_APP_MAIN); 574 attr.put(Attributes.Name.CLASS_PATH, "a.jar:b.jar"); 575 //parameters in jar should be ok 576 doTest_existingJar(m, params); 577 } 578 579 @Test 580 public void testPackageAsJar_existingJar_multipleInputs() 581 throws PackagerException, IOException { 582 //We only "update" jar file if it is THE ONLY input 583 //Otherwise we silently add jar as "jar" entry 584 585 CreateJarParams params = defaultParams(); 586 params.applicationClass = DUMMY_APP_MAIN; 587 588 File f = File.createTempFile("junk", "class"); 589 String dummyEntry = "dummy"; 590 params.resources.add(new PackagerResource(f.getParentFile(), f)); 591 592 File inputJar = createTestJar(null, dummyEntry); 593 594 if (params == null) { 595 params = new CreateJarParams(); 596 } 597 598 //common settings 599 params.outdir = dest.getRoot(); 600 params.outfile = "temp"; 601 params.embedLauncher = true; 602 params.css2bin = false; 603 params.resources.add( 604 new PackagerResource(inputJar.getParentFile(), inputJar)); 605 606 lib.packageAsJar(params); 607 608 try (JarFile jar = new JarFile(new File(dest.getRoot(), "temp.jar"))) { 609 JarEntry je = jar.getJarEntry(dummyEntry); 610 assertNull("Do NOT expect jar content to be copied.", je); 611 } 612 } 613 614 @Test 615 @Ignore 616 public void testPackageAsJar_existingJar_sameJar() 617 throws IOException, PackagerException { 618 String dummyJarEntryName = DUMMY_APP_MAIN; 619 File inputJar = createTestJar(null, dummyJarEntryName); 620 621 CreateJarParams params = defaultParams(); 622 623 //common settings 624 params.outdir = inputJar.getParentFile(); 625 params.outfile = inputJar.getName(); 626 params.embedLauncher = true; 627 params.resources.add( 628 new PackagerResource(inputJar.getParentFile(), inputJar)); 629 630 lib.packageAsJar(params); 631 632 633 //validate have launcher class and original content 634 JarFile jar = new JarFile(inputJar); 635 Attributes attrs = jar.getManifest().getMainAttributes(); 636 assertEquals("Main class should point to JavaFX launcher", 637 "com/javafx/main/Main", attrs.get(Attributes.Name.MAIN_CLASS)); 638 assertEquals("Unexpected app main", 639 DUMMY_APP_MAIN, attrs.getValue("JavaFX-Application-Class")); 640 641 try { 642 JarEntry je = jar.getJarEntry(dummyJarEntryName); 643 assertNotNull("Do NOT expect jar content to be copied.", je); 644 } finally { 645 jar.close(); 646 } 647 648 } 649 650 private static class SimpleErrorHandler implements ErrorHandler { 651 652 public SimpleErrorHandler() { 653 } 654 655 public void warning(SAXParseException saxpe) throws SAXException { 656 saxpe.printStackTrace(); 657 fail("Warning"); 658 } 659 660 public void error(SAXParseException saxpe) throws SAXException { 661 saxpe.printStackTrace(); 662 fail("Parsing error"); 663 } 664 665 public void fatalError(SAXParseException saxpe) throws SAXException { 666 saxpe.printStackTrace(); 667 fail("Fatal error"); 668 } 669 } 670 671 }