1 /*
   2  * Copyright (c) 2011, 2016, 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.oracle.tools.packager.*;
  29 import com.sun.javafx.tools.packager.bundlers.Bundler.BundleType;
  30 import com.oracle.tools.packager.ConfigException;
  31 import com.oracle.tools.packager.UnsupportedPlatformException;
  32 
  33 import java.io.File;
  34 import java.io.FileInputStream;
  35 import java.io.IOException;
  36 import java.text.MessageFormat;
  37 import java.util.*;
  38 import jdk.packager.internal.JLinkBundlerHelper;
  39 
  40 
  41 public class Main {
  42 
  43     private static final ResourceBundle bundle =
  44             ResourceBundle.getBundle("com/sun/javafx/tools/packager/Bundle");
  45 
  46     private static final String version = bundle.getString("MSG_Version")
  47             + " " + PackagerLib.JAVAFX_VERSION + "\n";
  48     private static final String help = bundle.getString("MSG_Help_1")
  49                                         + bundle.getString("MSG_Help_2")
  50                                         + bundle.getString("MSG_Help_3")
  51                                         + bundle.getString("MSG_Help_4")
  52                                         + bundle.getString("MSG_Help_5")
  53                                         + bundle.getString("MSG_Help_6")
  54                                         + bundle.getString("MSG_Help_7");
  55 
  56     private static String nextArg(String args[], int i) {
  57         return (i == args.length - 1) ? "" : args[i + 1];
  58     }
  59 
  60     private static boolean verbose = false;
  61     private static boolean packageAsJar = false;
  62     private static boolean genJNLP = false;
  63     private static boolean genPackages = false;
  64     private static boolean css2Bin = false;
  65     private static boolean signJar = false;
  66     private static boolean makeAll = false;
  67 
  68     private static void addResources(CommonParams commonParams,
  69                                      String baseDir, String s) {
  70         if (s == null || "".equals(s)) {
  71             return;
  72         }
  73 
  74         String ls = ".";
  75 
  76         if (s != null) {
  77             ls = s;
  78         }
  79 
  80         String[] pathArray = ls.split(File.pathSeparator);
  81 
  82         File lbaseDir = null;
  83 
  84         if (baseDir != null) {
  85             lbaseDir = new File(baseDir);
  86         }
  87 
  88         for (final String path: pathArray) {
  89             commonParams.addResource(lbaseDir, path);
  90         }
  91     }
  92 
  93     private static void addArgument(DeployParams deployParams, String argument) {
  94         if (deployParams.arguments != null) {
  95             deployParams.arguments.add(argument);
  96         } else {
  97             List<String> list = new LinkedList<>();
  98             list.add(argument);
  99             deployParams.setArguments(list);
 100         }
 101     }
 102 
 103     private static void addArgument(CreateJarParams deployParams, String argument) {
 104         if (deployParams.arguments != null) {
 105             deployParams.arguments.add(argument);
 106         } else {
 107             List<String> list = new LinkedList<>();
 108             list.add(argument);
 109             deployParams.setArguments(list);
 110         }
 111     }
 112 
 113     private static Map<String, String> createAttrMap(String arg) {
 114         Map<String, String> map = new HashMap<>();
 115         if (arg == null || "".equals(arg)) {
 116             return null;
 117         }
 118         String[] pairsArray = arg.split(",");
 119         for (String pair: pairsArray) {
 120             String[] attr = pair.split("=");
 121             map.put(attr[0].trim(), attr[1].trim());
 122         }
 123         return map;
 124     }
 125 
 126     private static List<Param> parseParams(String filename) throws IOException {
 127         File paramFile = new File(filename);
 128         Properties properties = new Properties();
 129         FileInputStream in = new FileInputStream(paramFile);
 130         properties.load(in);
 131         in.close();
 132 
 133         List<Param> parameters = new ArrayList<>(properties.size());
 134 
 135         for (Map.Entry en : properties.entrySet()) {
 136             Param p = new Param();
 137             p.setName((String)en.getKey());
 138             p.setValue((String)en.getValue());
 139             parameters.add(p);
 140         }
 141         return parameters;
 142     }
 143 
 144     private static List<HtmlParam> parseHtmlParams(String filename) throws IOException {
 145         File paramFile = new File(filename);
 146         Properties properties = new Properties();
 147         FileInputStream in = new FileInputStream(paramFile);
 148         properties.load(in);
 149         in.close();
 150 
 151         List<HtmlParam> parameters = new ArrayList<>(properties.size());
 152 
 153         for (Map.Entry en : properties.entrySet()) {
 154             HtmlParam p = new HtmlParam();
 155             p.setName((String)en.getKey());
 156             p.setValue((String)en.getValue());
 157             parameters.add(p);
 158         }
 159         return parameters;
 160     }
 161 
 162     private static List<JSCallback> parseCallbacks(String param) {
 163         String[] callbacks = param.split(",");
 164         List<JSCallback> list = new ArrayList<>(callbacks.length);
 165 
 166         for (String cb: callbacks) {
 167             String[] nameCmd = cb.split(":");
 168             if (nameCmd.length == 2) {
 169                 list.add(new JSCallback(nameCmd[0], nameCmd[1]));
 170             }
 171         }
 172         return list;
 173     }
 174 
 175 
 176     @SuppressWarnings("deprecation")
 177     public static void main(String... args) throws Exception {
 178         if (args.length == 0 || args.length == 1 && args[0].equals("-help")) {
 179             System.out.println(help);
 180         } else if (args.length == 1 && args[0].equals("-version")) {
 181             System.out.println(version);
 182         } else {
 183             PackagerLib packager = new PackagerLib();
 184             CreateJarParams createJarParams = new CreateJarParams();
 185             DeployParams deployParams = new DeployParams();
 186             CreateBSSParams createBssParams = new CreateBSSParams();
 187             SignJarParams signJarParams = new SignJarParams();
 188             MakeAllParams makeAllParams = new MakeAllParams();
 189             String srcdir = null;
 190             String srcfiles = null;
 191 
 192             try {
 193                 if (args[0].equalsIgnoreCase("-createjar")) {
 194                     for (int i = 1; i < args.length; i++) {
 195                         String arg = args[i];
 196                         if (arg.equalsIgnoreCase("-appclass")) {
 197                             createJarParams.setApplicationClass(nextArg(args, i++));
 198                         } else if (arg.equalsIgnoreCase("-preloader")) {
 199                             createJarParams.setPreloader(nextArg(args, i++));
 200                         } else if (arg.equalsIgnoreCase("-classpath")) {
 201                             createJarParams.setClasspath(nextArg(args, i++));
 202                         } else if (arg.equalsIgnoreCase("-manifestAttrs")) {
 203                             createJarParams.setManifestAttrs(createAttrMap(nextArg(args, i++)));
 204                         } else if (arg.equalsIgnoreCase("-noembedlauncher")) {
 205                             System.err.println("-noembedlauncher is deprecated");
 206                         } else if (arg.equalsIgnoreCase("-nocss2bin")) {
 207                             createJarParams.setCss2bin(false);
 208                         } else if (arg.equalsIgnoreCase("-runtimeVersion")) {
 209                             createJarParams.setFxVersion(nextArg(args, i++));
 210                             System.err.println("-runtimeVersion is deprecated");
 211                         } else if (arg.equalsIgnoreCase("-verbose") || arg.equalsIgnoreCase("-v")) {
 212                             createJarParams.setVerbose(true);
 213                             verbose = true;
 214                         } else if (arg.equalsIgnoreCase("-outdir")) {
 215                             createJarParams.setOutdir(new File(nextArg(args, i++)));
 216                         } else if (arg.equalsIgnoreCase("-outfile")) {
 217                             createJarParams.setOutfile(nextArg(args, i++));
 218                         } else if (arg.equalsIgnoreCase("-" + StandardBundlerParam.SOURCE_DIR.getID())) {
 219                             srcdir = nextArg(args, i++);
 220                         } else if (arg.equalsIgnoreCase("-srcfiles")) {
 221                             srcfiles = nextArg(args, i++);
 222                         } else if (arg.equalsIgnoreCase("-argument")) {
 223                             addArgument(createJarParams, nextArg(args, i++));
 224                         }  else if (arg.equalsIgnoreCase("-paramFile")) {
 225                             createJarParams.setParams(parseParams(nextArg(args, i++)));
 226                         } else {
 227                             throw new PackagerException("ERR_UnknownArgument", arg);
 228                         }
 229                     }
 230 
 231                     addResources(createJarParams, srcdir, srcfiles);
 232                     packageAsJar = true;
 233                 } else if (args[0].equalsIgnoreCase("-deploy")) {
 234                     File templateInFile = null;
 235                     File templateOutFile = null;
 236                     deployParams.setBundleType(BundleType.JNLP);
 237                     deployParams.setTargetFormat("jnlp");
 238 
 239 
 240                     //can only set it to true with command line, reset default
 241                     deployParams.setEmbedJNLP(false);
 242                     for (int i = 1; i < args.length; i++) {
 243                         String arg = args[i];
 244                         if (arg.startsWith("-B")) {
 245                             String key;
 246                             String value;
 247 
 248                             int keyStart = 2;
 249                             int equals = arg.indexOf("=");
 250                             int len = arg.length();
 251                             if (equals < keyStart) {
 252                                 if (keyStart < len) {
 253                                     key = arg.substring(keyStart, len);
 254                                     value = Boolean.TRUE.toString();
 255                                 } else {
 256                                     continue;
 257                                 }
 258                             } else if (keyStart < equals) {
 259                                 key = arg.substring(keyStart, equals);
 260                                 value = arg.substring(equals+1, len);
 261                             } else {
 262                                 continue;
 263                             }
 264                             deployParams.addBundleArgument(key, value);
 265                         } else if (arg.equalsIgnoreCase("-title")) {
 266                             deployParams.setTitle(nextArg(args, i++));
 267                         } else if (arg.equalsIgnoreCase("-vendor")) {
 268                             deployParams.setVendor(nextArg(args, i++));
 269                         } else if (arg.equalsIgnoreCase("-native")) {
 270                             //if no argument is provided we will treat it as ALL
 271                             // for compatibility with FX 2.2
 272                             BundleType type = BundleType.ALL;
 273                             String format = null; //null means ANY
 274                             if (i+1 < args.length && !args[i+1].startsWith("-")) {
 275                                 String v = args[++i];
 276                                 //parsing logic is the same as in DeployFXTask
 277                                 if ("image".equals(v)) {
 278                                     type = BundleType.IMAGE;
 279                                 } else if ("installer".equals(v)) {
 280                                     type = BundleType.INSTALLER;
 281                                 } else {
 282                                     //assume it is request to build only specific format
 283                                     // (like exe or msi)
 284                                     format = (v != null) ? v.toLowerCase() : null;
 285                                 }
 286                             }
 287                             deployParams.setBundleType(type);
 288                             deployParams.setTargetFormat(format);
 289                         } else if (arg.equalsIgnoreCase("-description")) {
 290                             deployParams.setDescription(nextArg(args, i++));
 291                         } else if(arg.equalsIgnoreCase("-appclass")) {
 292                             deployParams.setApplicationClass(nextArg(args, i++));
 293                         } else if(arg.equalsIgnoreCase("-daemon")) {
 294                             deployParams.setServiceHint(true);
 295                         } else if(arg.equalsIgnoreCase("-installdirChooser")) {
 296                             deployParams.setInstalldirChooser(true);
 297                         } else if (arg.equalsIgnoreCase("-preloader")) {
 298                             deployParams.setPreloader(nextArg(args, i++));
 299                         } else if (arg.equalsIgnoreCase("-paramFile")) {
 300                             deployParams.setParams(parseParams(nextArg(args, i++)));
 301                         } else if (arg.equalsIgnoreCase("-htmlParamFile")) {
 302                             deployParams.setHtmlParams(parseHtmlParams(nextArg(args, i++)));
 303                         } else if (arg.equalsIgnoreCase("-width")) {
 304                             deployParams.setWidth(Integer.parseInt(nextArg(args, i++)));
 305                         } else if (arg.equalsIgnoreCase("-height")) {
 306                             deployParams.setHeight(Integer.parseInt(nextArg(args, i++)));
 307                         } else if (arg.equalsIgnoreCase("-name")) {
 308                             deployParams.setAppName(nextArg(args, i++));
 309                         } else if (arg.equalsIgnoreCase("-embedJNLP")) {
 310                             deployParams.setEmbedJNLP(true);
 311                         } else if (arg.equalsIgnoreCase("-embedCertificates")) {
 312                             System.err.println("-embedCertificates is deprecated");
 313                         } else if (arg.equalsIgnoreCase("-allpermissions")) {
 314                             deployParams.setAllPermissions(true);
 315                         } else if (arg.equalsIgnoreCase("-updatemode")) {
 316                             deployParams.setUpdateMode(nextArg(args, i++));
 317                         } else if (arg.equalsIgnoreCase("-isExtension")) {
 318                             deployParams.setExtension(true);
 319                         } else if (arg.equalsIgnoreCase("-callbacks")) {
 320                             deployParams.setJSCallbacks(parseCallbacks(nextArg(args, i++)));
 321                         } else if (arg.equalsIgnoreCase("-templateInFilename")) {
 322                             templateInFile = new File(nextArg(args, i++));
 323                         } else if (arg.equalsIgnoreCase("-templateOutFilename")) {
 324                             templateOutFile = new File(nextArg(args, i++));
 325                         } else if (arg.equalsIgnoreCase("-appId") || arg.equalsIgnoreCase("-templateId")) {
 326                             String appIdArg = nextArg(args, i++);
 327                             deployParams.setAppId(appIdArg);
 328                             deployParams.setId(appIdArg);
 329                         } else if (arg.equalsIgnoreCase("-verbose") || arg.equalsIgnoreCase("-v")) {
 330                             deployParams.setVerbose(true);
 331                             verbose = true;
 332                         } else if (arg.equalsIgnoreCase("-includedt")) {
 333                             deployParams.setIncludeDT(true);
 334                         } else if (arg.equalsIgnoreCase("-outdir")) {
 335                             deployParams.setOutdir(new File(nextArg(args, i++)));
 336                         } else if (arg.equalsIgnoreCase("-outfile")) {
 337                             deployParams.setOutfile(nextArg(args, i++));
 338                         } else if (arg.equalsIgnoreCase("-" + StandardBundlerParam.SOURCE_DIR.getID())) {
 339                             srcdir = nextArg(args, i++);
 340                             deployParams.srcdir = srcdir;
 341                         } else if (arg.equalsIgnoreCase("-srcfiles")) {
 342                             srcfiles = nextArg(args, i++);
 343                         } else if (arg.equalsIgnoreCase("-argument")) {
 344                             addArgument(deployParams, nextArg(args, i++));
 345                         } else if (arg.equalsIgnoreCase("-nosign")) {
 346                             deployParams.setSignBundle(false);
 347                         } else if (arg.equals(ADD_MODULES)) {
 348                             deployParams.addModules.add(nextArg(args, i++));
 349                         } else if (arg.startsWith(ADD_MODULES + "=")) {
 350                             deployParams.addModules.add(arg.replace(ADD_MODULES + "=", ""));
 351                         } else if (arg.equals(LIMIT_MODULES)) {
 352                             deployParams.limitModules.add(nextArg(args, i++));
 353                         } else if (arg.startsWith(LIMIT_MODULES + "=")) {
 354                             deployParams.limitModules.add(arg.replace(LIMIT_MODULES + "=", ""));
 355                         } else if (arg.equals(STRIP_NATIVE_COMMANDS)) {
 356                             deployParams.setStripNativeCommands(Boolean.valueOf(nextArg(args, i++)));
 357                         } else if (arg.equals(STRIP_NATIVE_COMMANDS + "=")) {
 358                             deployParams.setStripNativeCommands(Boolean.valueOf(arg.replace(STRIP_NATIVE_COMMANDS + "=", "")));
 359                         } else if (arg.equals(DETECT_MODULES)) {
 360                             deployParams.setDetectModules(true);
 361                         } else if (arg.equals(MODULE_PATH) || arg.equals(P)) {
 362                             deployParams.modulePath = nextArg(args, i++);
 363                         } else if (arg.equals(MODULE_PATH + "=")) {
 364                             deployParams.modulePath = arg.replace(MODULE_PATH + "=", "");
 365                         } else if (arg.equals(MODULE) || arg.equals(M)) {
 366                             deployParams.setModule(nextArg(args, i++));
 367                         } else if (arg.equals(MODULE + "=")) {
 368                             deployParams.setModule(arg.replace(MODULE + "=", ""));
 369                         } else if (arg.startsWith(J_XDEBUG)) {
 370                             deployParams.setDebug(arg.replace(J_XDEBUG, ""));
 371                         } else {
 372                             throw new PackagerException("ERR_UnknownArgument", arg);
 373                         }
 374                     }
 375                     if (templateInFile != null) {
 376                         deployParams.addTemplate(templateInFile, templateOutFile);
 377                     }
 378 
 379                     if (deployParams.validateForJNLP()) {
 380                         genJNLP = true;
 381                     }
 382 
 383                     if (deployParams.validateForBundle()) {
 384                         genPackages = true;
 385                     }
 386 
 387                     addResources(deployParams, srcdir, srcfiles);
 388                 } else if (args[0].equalsIgnoreCase("-createbss")) {
 389                     for (int i = 1; i < args.length; i++) {
 390                         String arg = args[i];
 391                         if (arg.equalsIgnoreCase("-verbose") || arg.equalsIgnoreCase("-v")) {
 392                             createBssParams.setVerbose(true);
 393                             verbose = true;
 394                         } else if (arg.equalsIgnoreCase("-outdir")) {
 395                             createBssParams.setOutdir(new File(nextArg(args, i++)));
 396                         } else if (arg.equalsIgnoreCase("-srcdir")) {
 397                             srcdir = nextArg(args, i++);
 398                         } else if (arg.equalsIgnoreCase("-srcfiles")) {
 399                             srcfiles = nextArg(args, i++);
 400                         } else {
 401                             throw new PackagerException("ERR_UnknownArgument", arg);
 402                         }
 403                     }
 404 
 405                     addResources(createBssParams, srcdir, srcfiles);
 406                     css2Bin = true;
 407                 } else if (args[0].equalsIgnoreCase("-signJar")) {
 408                     for (int i = 1; i < args.length; i++) {
 409                         String arg = args[i];
 410                         if (arg.equalsIgnoreCase("-keyStore")) {
 411                             signJarParams.setKeyStore(new File(nextArg(args, i++)));
 412                         } else if(arg.equalsIgnoreCase("-alias")) {
 413                             signJarParams.setAlias(nextArg(args, i++));
 414                         } else if(arg.equalsIgnoreCase("-storePass")) {
 415                             signJarParams.setStorePass(nextArg(args, i++));
 416                         } else if(arg.equalsIgnoreCase("-keyPass")) {
 417                             signJarParams.setKeyPass(nextArg(args, i++));
 418                         } else if(arg.equalsIgnoreCase("-storeType")) {
 419                             signJarParams.setStoreType(nextArg(args, i++));
 420                         } else if(arg.equalsIgnoreCase("-verbose") || arg.equalsIgnoreCase("-v")) {
 421                             signJarParams.setVerbose(true);
 422                             verbose = true;
 423                         } else if (arg.equalsIgnoreCase("-outdir")) {
 424                             signJarParams.setOutdir(new File(nextArg(args, i++)));
 425                         } else if (arg.equalsIgnoreCase("-srcdir")) {
 426                             srcdir = nextArg(args, i++);
 427                         } else if (arg.equalsIgnoreCase("-srcfiles")) {
 428                             srcfiles = nextArg(args, i++);
 429                         } else {
 430                             throw new PackagerException("ERR_UnknownArgument", arg);
 431                         }
 432                     }
 433 
 434                     addResources(signJarParams, srcdir, srcfiles);
 435                     signJar = true;
 436                 } else if (args[0].equalsIgnoreCase("-makeall")) {
 437                     System.err.println("-makeall is deprecated");
 438                     for (int i = 1; i < args.length; i++) {
 439                         String arg = args[i];
 440                         if (arg.equalsIgnoreCase("-appclass")) {
 441                             makeAllParams.setAppClass(nextArg(args, i++));
 442                         } else if (arg.equalsIgnoreCase("-preloader")) {
 443                             makeAllParams.setPreloader(nextArg(args, i++));
 444                         } else if (arg.equalsIgnoreCase("-classpath")) {
 445                             makeAllParams.setClasspath(nextArg(args, i++));
 446                         } else if (arg.equalsIgnoreCase("-name")) {
 447                             makeAllParams.setAppName(nextArg(args, i++));
 448                         } else if(arg.equalsIgnoreCase("-width")) {
 449                             makeAllParams.setWidth(Integer.parseInt(nextArg(args, i++)));
 450                         } else if(arg.equalsIgnoreCase("-height")) {
 451                             makeAllParams.setHeight(Integer.parseInt(nextArg(args, i++)));
 452                         } else if(arg.equalsIgnoreCase("-v")) {
 453                             makeAllParams.setVerbose(true);
 454                         } else {
 455                             throw new PackagerException("ERR_UnknownArgument", arg);
 456                         }
 457                     }
 458                     makeAll = true;
 459                 } else if (args[0].equalsIgnoreCase("-help")) {
 460                     showBundlerHelp(args[1], args.length > 2 && "-verbose".equals(args[2]));
 461                 } else {
 462                     System.err.println(MessageFormat.format(
 463                                         bundle.getString("ERR_UnknownCommand"),
 464                                         args[0]));
 465                     System.exit(-1);
 466                 }
 467 
 468                 //set default logger
 469                 if (verbose) {
 470                     com.oracle.tools.packager.Log.setLogger(new com.oracle.tools.packager.Log.Logger(true));
 471                 } else {
 472                     com.oracle.tools.packager.Log.setLogger(new com.oracle.tools.packager.Log.Logger(false));
 473                 }
 474 
 475                 if (css2Bin) {
 476                     createBssParams.validate();
 477                     packager.generateBSS(createBssParams);
 478                 }
 479                 if (packageAsJar) {
 480                     createJarParams.validate();
 481                     packager.packageAsJar(createJarParams);
 482                 }
 483                 if (genJNLP) {
 484                     deployParams.validate();
 485                     packager.generateDeploymentPackages(deployParams);
 486                 }
 487                 if (genPackages) {
 488                     deployParams.setBundleType(BundleType.NATIVE);
 489                     deployParams.validate();
 490                     packager.generateDeploymentPackages(deployParams);
 491                 }
 492                 if (signJar) {
 493                     signJarParams.validate();
 494                     if (signJarParams.storePass == null) {
 495                         char[] passwd = System.console().readPassword(bundle.getString("MSG_EnterKeystorePassword"));
 496                         if (passwd == null) {
 497                             signJarParams.storePass = "";
 498                         } else {
 499                             signJarParams.storePass = new String(passwd);
 500                         }
 501                     }
 502                     if (signJarParams.keyPass == null) {
 503                         char[] passwd = System.console().readPassword(bundle.getString("MSG_EnterKeyPassword"), signJarParams.alias);
 504                         if (passwd == null) {
 505                             signJarParams.keyPass = "";
 506                         } else {
 507                             signJarParams.keyPass = new String(passwd);
 508                         }
 509                     }
 510                     packager.signJar(signJarParams);
 511                 }
 512                 if (makeAll) {
 513                     makeAllParams.validate();
 514                     packager.makeAll(makeAllParams);
 515                 }
 516 
 517             } catch (Exception e) {
 518                 if (verbose) {
 519                     throw e;
 520                 } else {
 521                     System.err.println(e.getMessage());
 522                     if (e.getCause() != null && e.getCause() != e) {
 523                         System.err.println(e.getCause().getMessage());
 524                     }
 525                     System.exit(-1);
 526                 }
 527             }
 528         }
 529     }
 530     private static final String J_XDEBUG = JLinkBundlerHelper.DEBUG.getID() + ":";
 531 
 532     private static final String MODULE = "--" + JLinkBundlerHelper.MODULE.getID();
 533     private static final String M = "-m";
 534     private static final String MODULE_PATH = "--" + JLinkBundlerHelper.MODULE_PATH.getID();
 535     private static final String P = "-p";
 536     private static final String ADD_MODULES = "--" + JLinkBundlerHelper.ADD_MODULES.getID();
 537     private static final String LIMIT_MODULES = "--" + JLinkBundlerHelper.LIMIT_MODULES.getID();
 538     private static final String STRIP_NATIVE_COMMANDS = "--" + JLinkBundlerHelper.STRIP_NATIVE_COMMANDS.getID();
 539     private static final String DETECT_MODULES = "--" + JLinkBundlerHelper.DETECT_MODULES.getID();
 540 
 541     public static void showBundlerHelp(String bundlerName, boolean verbose) {
 542         //TODO I18N
 543         if ("bundlers".equals(bundlerName)) {
 544             // enumerate bundlers
 545             System.out.println("Known Bundlers -- \n");
 546             for (Bundler bundler : Bundlers.createBundlersInstance().getBundlers()) {
 547                 try {
 548                     bundler.validate(new HashMap<>());
 549                 } catch (UnsupportedPlatformException upe) {
 550                     // don't list bundlers this platform cannot run
 551                     continue;
 552                 } catch (ConfigException ignore) {
 553                     // but requiring more than an empty map is perfectly fine.
 554                 //} catch (RuntimeException re) {
 555                 //    re.printStackTrace();
 556                 }
 557 
 558                 if (verbose) {
 559                     System.out.printf(
 560                             "%s - %s - %s\n\t%s\n",
 561                             bundler.getID(),
 562                             bundler.getName(),
 563                             bundler.getBundleType(),
 564                             bundler.getDescription()
 565                     );
 566                 } else {
 567                     System.out.printf(
 568                             "%s - %s - %s\n",
 569                             bundler.getID(),
 570                             bundler.getName(),
 571                             bundler.getBundleType()
 572                     );
 573                 }
 574             }
 575         } else {
 576             // enumerate parameters for a bundler
 577             for (Bundler bundler : Bundlers.createBundlersInstance().getBundlers()) {
 578                 if (bundler.getID().equals(bundlerName)) {
 579                     System.out.printf("Bundler Parameters for %s (%s) --\n", bundler.getName(), bundler.getID());
 580                     for (BundlerParamInfo bpi : bundler.getBundleParameters()) {
 581                         if (bpi.getStringConverter() == null) continue;
 582                         if (verbose) {
 583                             System.out.printf(
 584                                     "%s - %s - %s\n\t%s\n",
 585                                     bpi.getID(),
 586                                     bpi.getName(),
 587                                     bpi.getValueType().getSimpleName(),
 588                                     bpi.getDescription()
 589                             );
 590                         } else {
 591                             System.out.printf(
 592                                     "%s - %s - %s\n",
 593                                     bpi.getID(),
 594                                     bpi.getName(),
 595                                     bpi.getValueType().getSimpleName()
 596                             );
 597                         }
 598                     }
 599                     return;
 600                 }
 601             }
 602             System.out.printf("Sorry, no bundler matching the id %s was found.\n", bundlerName);
 603         }
 604     }
 605 }