1 /*
   2  * Copyright (c) 2014, 2015, 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.oracle.tools.packager.windows;
  27 
  28 import com.oracle.tools.packager.AbstractBundler;
  29 import com.oracle.tools.packager.Bundler;
  30 import com.oracle.tools.packager.BundlerParamInfo;
  31 import com.oracle.tools.packager.ConfigException;
  32 import com.oracle.tools.packager.Log;
  33 import com.oracle.tools.packager.RelativeFileSet;
  34 import com.oracle.tools.packager.UnsupportedPlatformException;
  35 import org.junit.After;
  36 import org.junit.Assume;
  37 import org.junit.Before;
  38 import org.junit.BeforeClass;
  39 import org.junit.Test;
  40 
  41 import java.io.File;
  42 import java.io.IOException;
  43 import java.util.ArrayList;
  44 import java.util.Arrays;
  45 import java.util.Collection;
  46 import java.util.HashMap;
  47 import java.util.HashSet;
  48 import java.util.List;
  49 import java.util.Map;
  50 import java.util.Set;
  51 import java.util.TreeMap;
  52 
  53 import static com.oracle.tools.packager.StandardBundlerParam.*;
  54 import static com.oracle.tools.packager.windows.WinAppBundler.ICON_ICO;
  55 import static com.oracle.tools.packager.windows.WindowsBundlerParam.WIN_RUNTIME;
  56 import static com.oracle.tools.packager.windows.WindowsBundlerParam.MENU_GROUP;
  57 import static com.oracle.tools.packager.windows.WindowsBundlerParam.INSTALLDIR_CHOOSER;
  58 import static org.junit.Assert.*;
  59  
  60 public class WinExeBundlerTest {
  61 
  62     static File tmpBase;
  63     static File workDir;
  64     static File appResourcesDir;
  65     static File fakeMainJar;
  66     static String runtimeJdk;
  67     static String runtimeJre;
  68     static Set<File> appResources;
  69     static boolean retain = false;
  70 
  71     @BeforeClass
  72     public static void prepareApp() {
  73         // only run on windows
  74         Assume.assumeTrue(System.getProperty("os.name").toLowerCase().startsWith("win"));
  75 
  76         runtimeJdk = System.getenv("PACKAGER_JDK_ROOT");
  77         runtimeJre = System.getenv("PACKAGER_JRE_ROOT");
  78 
  79         // only run if we have InnoSetup installed
  80         Assume.assumeNotNull(WinExeBundler.TOOL_INNO_SETUP_COMPILER_EXECUTABLE.fetchFrom(new HashMap<>()));
  81 
  82         Log.setLogger(new Log.Logger(true));
  83 
  84         retain = Boolean.parseBoolean(System.getProperty("RETAIN_PACKAGER_TESTS"));
  85 
  86         workDir = new File("build/tmp/tests", "winexe");
  87         appResourcesDir = new File("build/tmp/tests", "appResources");
  88         fakeMainJar = new File(appResourcesDir, "mainApp.jar");
  89 
  90         appResources = new HashSet<>(Arrays.asList(fakeMainJar,
  91                 new File(appResourcesDir, "LICENSE"),
  92                 new File(appResourcesDir, "LICENSE2")
  93         ));
  94     }
  95 
  96     @Before
  97     public void createTmpDir() throws IOException {
  98         if (retain) {
  99             tmpBase = new File("build/tmp/tests/winexe");
 100         } else {
 101             tmpBase = BUILD_ROOT.fetchFrom(new TreeMap<>());
 102         }
 103         tmpBase.mkdir();
 104     }
 105 
 106     @After
 107     public void maybeCleanupTmpDir() {
 108         if (!retain) {
 109             attemptDelete(tmpBase);
 110         }
 111     }
 112 
 113     private void attemptDelete(File tmpBase) {
 114         if (tmpBase.isDirectory()) {
 115             File[] children = tmpBase.listFiles();
 116             if (children != null) {
 117                 for (File f : children) {
 118                     attemptDelete(f);
 119                 }
 120             }
 121         }
 122         boolean success;
 123         try {
 124             success = !tmpBase.exists() || tmpBase.delete();
 125         } catch (SecurityException se) {
 126             success = false;
 127         }
 128         if (!success) {
 129             System.err.println("Could not clean up " + tmpBase.toString());
 130         }
 131     }
 132 
 133     /**
 134      * See if smoke comes out
 135      */
 136     @Test
 137     public void smokeTest() throws IOException, ConfigException, UnsupportedPlatformException {
 138         Bundler bundler = new WinExeBundler();
 139 
 140         assertNotNull(bundler.getName());
 141         assertNotNull(bundler.getID());
 142         assertNotNull(bundler.getDescription());
 143         //assertNotNull(bundler.getBundleParameters());
 144 
 145         Map<String, Object> bundleParams = new HashMap<>();
 146 
 147         bundleParams.put(BUILD_ROOT.getID(), tmpBase);
 148 
 149         bundleParams.put(APP_NAME.getID(), "Smoke Test");
 150         bundleParams.put(MAIN_CLASS.getID(), "hello.HelloRectangle");
 151         bundleParams.put(PREFERENCES_ID.getID(), "the/really/long/preferences/id");
 152         bundleParams.put(MAIN_JAR.getID(),
 153                 new RelativeFileSet(fakeMainJar.getParentFile(),
 154                         new HashSet<>(Arrays.asList(fakeMainJar)))
 155         );
 156         bundleParams.put(CLASSPATH.getID(), "mainApp.jar");
 157         bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
 158         bundleParams.put(LICENSE_FILE.getID(), Arrays.asList("LICENSE", "LICENSE2"));
 159         bundleParams.put(COPYRIGHT.getID(), "Copyright(c) 2014 the testers \"who like to break stuff\"");
 160         bundleParams.put(VERBOSE.getID(), true);
 161 
 162         boolean valid = bundler.validate(bundleParams);
 163         assertTrue(valid);
 164 
 165         File result = bundler.execute(bundleParams, new File(workDir, "smoke"));
 166         System.err.println("Bundle at - " + result);
 167         assertNotNull(result);
 168         assertTrue(result.exists());
 169     }
 170 
 171     /**
 172      * The bare minimum configuration needed to make it work
 173      * <ul>
 174      *     <li>Where to build it</li>
 175      *     <li>The jar containing the application (with a main-class attribute)</li>
 176      * </ul>
 177      * 
 178      * All other values will be driven off of those two values.
 179      */
 180     @Test
 181     public void minimumConfig() throws IOException, ConfigException, UnsupportedPlatformException {
 182         Bundler bundler = new WinExeBundler();
 183 
 184         Map<String, Object> bundleParams = new HashMap<>();
 185 
 186         bundleParams.put(BUILD_ROOT.getID(), tmpBase);
 187 
 188         bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
 189 
 190         File output = bundler.execute(bundleParams, new File(workDir, "BareMinimum"));
 191         System.err.println("Bundle at - " + output);
 192         assertNotNull(output);
 193         assertTrue(output.exists());
 194     }
 195 
 196     /**
 197      * Test a misconfiguration where the iscc tools are misconfigured.
 198      */
 199     @Test
 200     public void configISSCBad() throws IOException, ConfigException, UnsupportedPlatformException {
 201         Bundler bundler = new WinExeBundler();
 202 
 203         Map<String, Object> bundleParams = new HashMap<>();
 204 
 205         bundleParams.put(BUILD_ROOT.getID(), tmpBase);
 206         bundleParams.put(VERBOSE.getID(), true);
 207 
 208         bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
 209 
 210         bundleParams.put(WinExeBundler.TOOL_INNO_SETUP_COMPILER_EXECUTABLE.getID(), "c:\\MissingTool.exe");
 211 
 212         File output = bundler.execute(bundleParams, new File(workDir, "BadISSC"));
 213         assertNull(output);
 214     }
 215 
 216     /**
 217      * Test a misconfiguration where the iscc tools are misconfigured.
 218      */
 219     @Test
 220     public void configISSCNull() throws IOException, ConfigException, UnsupportedPlatformException {
 221         Bundler bundler = new WinExeBundler();
 222 
 223         Map<String, Object> bundleParams = new HashMap<>();
 224 
 225         bundleParams.put(BUILD_ROOT.getID(), tmpBase);
 226         bundleParams.put(VERBOSE.getID(), true);
 227 
 228         bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
 229 
 230         bundleParams.put(WinExeBundler.TOOL_INNO_SETUP_COMPILER_EXECUTABLE.getID(), null);
 231 
 232         File output = bundler.execute(bundleParams, new File(workDir, "NullISSC"));
 233         assertNull(output);
 234     }
 235 
 236     @Test(expected = ConfigException.class)
 237     public void invalidLicenseFile() throws ConfigException, UnsupportedPlatformException {
 238         Bundler bundler = new WinExeBundler();
 239 
 240         Map<String, Object> bundleParams = new HashMap<>();
 241 
 242         bundleParams.put(BUILD_ROOT.getID(), tmpBase);
 243 
 244         bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
 245         bundleParams.put(LICENSE_FILE.getID(), "BOGUS_LICENSE");
 246 
 247         bundler.validate(bundleParams);
 248     }
 249 
 250     @Test(expected = ConfigException.class)
 251     public void invalidCopyright() throws ConfigException, UnsupportedPlatformException {
 252         Bundler bundler = new WinExeBundler();
 253 
 254         Map<String, Object> bundleParams = new HashMap<>();
 255 
 256         bundleParams.put(BUILD_ROOT.getID(), tmpBase);
 257 
 258         bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
 259         bundleParams.put(COPYRIGHT.getID(), "Copyright (c) 2014 The Testers\nWho like to break stuff");
 260 
 261         bundler.validate(bundleParams);
 262     }
 263 
 264     @Test(expected = ConfigException.class)
 265     public void longCopyright() throws ConfigException, UnsupportedPlatformException {
 266         Bundler bundler = new WinExeBundler();
 267 
 268         Map<String, Object> bundleParams = new HashMap<>();
 269 
 270         bundleParams.put(BUILD_ROOT.getID(), tmpBase);
 271 
 272         bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
 273         bundleParams.put(COPYRIGHT.getID(), "Copyright (c) 2014 Way to many people to name because there are just so may of them I don't know where to start but I will just start with Alice, Bob, Charlie, Dave, Eve, well, there are just too many to say.");
 274 
 275         bundler.validate(bundleParams);
 276     }
 277 
 278     @Test
 279     public void configureEverything() throws Exception {
 280         AbstractBundler bundler = new WinExeBundler();
 281         Collection<BundlerParamInfo<?>> parameters = bundler.getBundleParameters();
 282 
 283         Map<String, Object> bundleParams = new HashMap<>();
 284 
 285         bundleParams.put(APP_NAME.getID(), "Everything App Name");
 286         bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
 287         bundleParams.put(ARGUMENTS.getID(), Arrays.asList("He Said", "She Said"));
 288         bundleParams.put(CLASSPATH.getID(), "mainApp.jar");
 289         bundleParams.put(ICON_ICO.getID(), new File(appResourcesDir, "javalogo_white_48.ico"));
 290         bundleParams.put(JVM_OPTIONS.getID(), "-Xms128M");
 291         bundleParams.put(JVM_PROPERTIES.getID(), "everything.jvm.property=everything.jvm.property.value");
 292         bundleParams.put(MAIN_CLASS.getID(), "hello.HelloRectangle");
 293         bundleParams.put(MAIN_JAR.getID(), "mainApp.jar");
 294         bundleParams.put(PREFERENCES_ID.getID(), "everything/preferences/id");
 295         bundleParams.put(PRELOADER_CLASS.getID(), "hello.HelloPreloader");
 296         bundleParams.put(USER_JVM_OPTIONS.getID(), "-Xmx=256M\n");
 297         bundleParams.put(VERSION.getID(), "1.2.3.4");
 298         bundleParams.put(WIN_RUNTIME.getID(), System.getProperty("java.home"));
 299 
 300         bundleParams.put(COPYRIGHT.getID(), "(C) 2014 Everything Copyright");
 301         bundleParams.put(DESCRIPTION.getID(), "Everything Description");
 302         bundleParams.put(LICENSE_FILE.getID(), "LICENSE");
 303         bundleParams.put(MENU_GROUP.getID(), "EverythingMenuGroup");
 304         bundleParams.put(MENU_HINT.getID(), true);
 305 //                RUN_AT_STARTUP,
 306         bundleParams.put(SHORTCUT_HINT.getID(), true);
 307 //                SERVICE_HINT,
 308 //                START_ON_INSTALL,
 309 //                STOP_ON_UNINSTALL,
 310         bundleParams.put(SYSTEM_WIDE.getID(), false);
 311         bundleParams.put(INSTALLDIR_CHOOSER.getID(), true);
 312         bundleParams.put(TITLE.getID(), "Everything Title");
 313         bundleParams.put(VENDOR.getID(), "Packager Tests");
 314 
 315         // assert they are set
 316         for (BundlerParamInfo bi :parameters) {
 317             assertTrue("Bundle args should contain " + bi.getID(), bundleParams.containsKey(bi.getID()));
 318         }
 319 
 320         // and only those are set
 321         bundleParamLoop:
 322         for (String s :bundleParams.keySet()) {
 323             for (BundlerParamInfo<?> bpi : parameters) {
 324                 if (s.equals(bpi.getID())) {
 325                     continue bundleParamLoop;
 326                 }
 327             }
 328             fail("Enumerated parameters does not contain " + s);
 329         }
 330 
 331         // assert they resolve
 332         for (BundlerParamInfo bi :parameters) {
 333             bi.fetchFrom(bundleParams);
 334         }
 335 
 336         // add verbose now that we are done scoping out parameters
 337         bundleParams.put(BUILD_ROOT.getID(), tmpBase);
 338         bundleParams.put(VERBOSE.getID(), true);
 339 
 340         // assert it validates
 341         boolean valid = bundler.validate(bundleParams);
 342         assertTrue(valid);
 343 
 344         // only run the bundle with full tests
 345         Assume.assumeTrue(Boolean.parseBoolean(System.getProperty("FULL_TEST")));
 346 
 347         File result = bundler.execute(bundleParams, new File(workDir, "everything"));
 348         System.err.println("Bundle at - " + result);
 349         assertNotNull(result);
 350         assertTrue(result.exists());
 351     }
 352 
 353 
 354     /**
 355      * multiple launchers
 356      */
 357     @Test
 358     public void twoLaunchersTest() throws IOException, ConfigException, UnsupportedPlatformException {
 359         Bundler bundler = new WinExeBundler();
 360 
 361         assertNotNull(bundler.getName());
 362         assertNotNull(bundler.getID());
 363         assertNotNull(bundler.getDescription());
 364         //assertNotNull(bundler.getBundleParameters());
 365 
 366         Map<String, Object> bundleParams = new HashMap<>();
 367 
 368         bundleParams.put(BUILD_ROOT.getID(), tmpBase);
 369 
 370         bundleParams.put(APP_NAME.getID(), "Two Launchers Test");
 371         bundleParams.put(MAIN_CLASS.getID(), "hello.HelloRectangle");
 372         bundleParams.put(PREFERENCES_ID.getID(), "the/really/long/preferences/id");
 373         bundleParams.put(MAIN_JAR.getID(),
 374                 new RelativeFileSet(fakeMainJar.getParentFile(),
 375                         new HashSet<>(Arrays.asList(fakeMainJar)))
 376         );
 377         bundleParams.put(CLASSPATH.getID(), "mainApp.jar");
 378         bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
 379         bundleParams.put(VERBOSE.getID(), true);
 380 
 381         List<Map<String, ? super Object>> secondaryLaunchers = new ArrayList<>();
 382         for (String name : new String[] {"Fire", "More Fire"}) {
 383             Map<String, ? super Object> launcher = new HashMap<>();
 384             launcher.put(APP_NAME.getID(), name);
 385             launcher.put(PREFERENCES_ID.getID(), "secondary/launcher/" + name);
 386             secondaryLaunchers.add(launcher);
 387         }
 388         bundleParams.put(SECONDARY_LAUNCHERS.getID(), secondaryLaunchers);
 389 
 390         boolean valid = bundler.validate(bundleParams);
 391         assertTrue(valid);
 392 
 393         File output = bundler.execute(bundleParams, new File(workDir, "launchers"));
 394         assertNotNull(output);
 395         assertTrue(output.exists());
 396     }
 397 
 398     /**
 399      * Set File Association
 400      */
 401     @Test
 402     public void testFileAssociation()
 403         throws IOException, ConfigException, UnsupportedPlatformException
 404     {
 405         // only run the bundle with full tests
 406         Assume.assumeTrue(Boolean.parseBoolean(System.getProperty("FULL_TEST")));
 407 
 408         testFileAssociation("FASmoke 1", "Bogus File", "bogus", "application/x-vnd.test-bogus",
 409                             new File(appResourcesDir, "small.ico"), false);
 410     }
 411 
 412     @Test
 413     public void testFileAssociationWithNullExtension()
 414         throws IOException, ConfigException, UnsupportedPlatformException
 415     {
 416         // association with no extension is still valid case (see RT-38625)
 417         testFileAssociation("FASmoke null", "Bogus File", null, "application/x-vnd.test-bogus",
 418                             new File(appResourcesDir, "small.ico"), true);
 419     }
 420 
 421     @Test
 422     public void testFileAssociationWithMultipleExtension()
 423             throws IOException, ConfigException, UnsupportedPlatformException
 424     {
 425         // only run the bundle with full tests
 426         Assume.assumeTrue(Boolean.parseBoolean(System.getProperty("FULL_TEST")));
 427 
 428         testFileAssociation("FASmoke ME", "Bogus File", "bogus fake", "application/x-vnd.test-bogus",
 429                 new File(appResourcesDir, "small.ico"), false);
 430     }
 431 
 432     @Test
 433     public void testMultipleFileAssociation()
 434             throws IOException, ConfigException, UnsupportedPlatformException
 435     {
 436         // only run the bundle with full tests
 437         Assume.assumeTrue(Boolean.parseBoolean(System.getProperty("FULL_TEST")));
 438 
 439         testFileAssociationMultiples("FASmoke MA",
 440                 new String[]{"Bogus File", "Fake file"},
 441                 new String[]{"bogus", "fake"},
 442                 new String[]{"application/x-vnd.test-bogus", "application/x-vnd.test-fake"},
 443                 new File[]{new File(appResourcesDir, "small.ico"), new File(appResourcesDir, "small.ico")}, true);
 444     }
 445 
 446     @Test
 447     public void testMultipleFileAssociationWithMultipleExtension()
 448             throws IOException, ConfigException, UnsupportedPlatformException
 449     {
 450         // association with no extension is still valid case (see RT-38625)
 451         testFileAssociationMultiples("FASmoke MAME",
 452                 new String[]{"Bogus File", "Fake file"},
 453                 new String[]{"bogus boguser", "fake faker"},
 454                 new String[]{"application/x-vnd.test-bogus", "application/x-vnd.test-fake"},
 455                 new File[]{new File(appResourcesDir, "small.ico"), new File(appResourcesDir, "small.ico")}, false);
 456     }
 457 
 458     private void testFileAssociation(String appName, String description, String extensions,
 459                                      String contentType, File icon, boolean systemWide)
 460             throws IOException, ConfigException, UnsupportedPlatformException
 461     {
 462         testFileAssociationMultiples(appName, new String[] {description}, new String[] {extensions},
 463                 new String[] {contentType}, new File[] {icon}, systemWide);
 464     }
 465 
 466     private void testFileAssociationMultiples(String appName, String[] description, String[] extensions,
 467                                               String[] contentType, File[] icon, boolean systemWide)
 468             throws IOException, ConfigException, UnsupportedPlatformException
 469     {
 470         assertEquals("Sanity: description same length as extensions", description.length, extensions.length);
 471         assertEquals("Sanity: extensions same length as contentType", extensions.length, contentType.length);
 472         assertEquals("Sanity: contentType same length as icon", contentType.length, icon.length);
 473 
 474         AbstractBundler bundler = new WinExeBundler();
 475 
 476         assertNotNull(bundler.getName());
 477         assertNotNull(bundler.getID());
 478         assertNotNull(bundler.getDescription());
 479         //assertNotNull(bundler.getBundleParameters());
 480 
 481         Map<String, Object> bundleParams = new HashMap<>();
 482 
 483         bundleParams.put(BUILD_ROOT.getID(), tmpBase);
 484 
 485         bundleParams.put(APP_NAME.getID(), appName);
 486         bundleParams.put(MAIN_CLASS.getID(), "hello.HelloRectangle");
 487         bundleParams.put(MAIN_JAR.getID(),
 488                 new RelativeFileSet(fakeMainJar.getParentFile(),
 489                         new HashSet<>(Arrays.asList(fakeMainJar)))
 490         );
 491         bundleParams.put(CLASSPATH.getID(), "mainApp.jar");
 492         bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
 493         bundleParams.put(VERBOSE.getID(), true);
 494         bundleParams.put(SYSTEM_WIDE.getID(), systemWide);
 495         bundleParams.put(VENDOR.getID(), "Packager Tests");
 496 
 497         List<Map<String, Object>> associations = new ArrayList<>();
 498 
 499         for (int i = 0; i < description.length; i++) {
 500             Map<String, Object> fileAssociation = new HashMap<>();
 501             fileAssociation.put(FA_DESCRIPTION.getID(), description[i]);
 502             fileAssociation.put(FA_EXTENSIONS.getID(), extensions[i]);
 503             fileAssociation.put(FA_CONTENT_TYPE.getID(), contentType[i]);
 504             fileAssociation.put(FA_ICON.getID(), icon[i]);
 505 
 506             associations.add(fileAssociation);
 507         }
 508 
 509         bundleParams.put(FILE_ASSOCIATIONS.getID(), associations);
 510 
 511         boolean valid = bundler.validate(bundleParams);
 512         assertTrue(valid);
 513 
 514         File result = bundler.execute(bundleParams, new File(workDir, APP_FS_NAME.fetchFrom(bundleParams)));
 515         System.err.println("Bundle at - " + result);
 516         assertNotNull(result);
 517         assertTrue(result.exists());
 518     }
 519 
 520     /**
 521      * Turn on AppCDS
 522      */
 523     @Test
 524     public void testAppCDS() throws IOException, ConfigException, UnsupportedPlatformException {
 525         Bundler bundler = new WinExeBundler();
 526 
 527         Map<String, Object> bundleParams = new HashMap<>();
 528 
 529         // not part of the typical setup, for testing
 530         bundleParams.put(BUILD_ROOT.getID(), tmpBase);
 531         bundleParams.put(VERBOSE.getID(), true);
 532         if (runtimeJdk != null) {
 533             bundleParams.put(WIN_RUNTIME.getID(), runtimeJdk);
 534         }
 535 
 536         bundleParams.put(APP_NAME.getID(), "AppCDS");
 537         bundleParams.put(IDENTIFIER.getID(), "com.example.appcds.exe.Test");
 538         bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
 539         bundleParams.put(UNLOCK_COMMERCIAL_FEATURES.getID(), true);
 540         bundleParams.put(ENABLE_APP_CDS.getID(), true);
 541 
 542         boolean valid = bundler.validate(bundleParams);
 543         assertTrue(valid);
 544 
 545         File output = bundler.execute(bundleParams, new File(workDir, "CDSTest"));
 546         System.err.println("Bundle at - " + output);
 547         assertNotNull(output);
 548         assertTrue(output.exists());
 549     }
 550     
 551 }