1 16 17 package org.apache.commons.launcher; 18 19 import java.io.File ; 20 import java.io.IOException ; 21 import java.io.PrintStream ; 22 import java.net.URL ; 23 import java.net.URLClassLoader ; 24 import java.net.URLDecoder ; 25 import java.util.ResourceBundle ; 26 27 import org.apache.commons.launcher.types.ArgumentSet; 28 import org.apache.commons.launcher.types.JVMArgumentSet; 29 import org.apache.commons.launcher.types.SysPropertySet; 30 import org.apache.tools.ant.Main; 31 import org.apache.tools.ant.Project; 32 import org.apache.tools.ant.ProjectHelper; 33 import org.apache.tools.ant.taskdefs.Ant; 34 import org.apache.tools.ant.taskdefs.Available; 35 import org.apache.tools.ant.taskdefs.CallTarget; 36 import org.apache.tools.ant.taskdefs.ConditionTask; 37 import org.apache.tools.ant.taskdefs.Exit; 38 import org.apache.tools.ant.taskdefs.Property; 39 import org.apache.tools.ant.taskdefs.Mkdir; 40 import org.apache.tools.ant.taskdefs.Copy; 41 import org.apache.tools.ant.taskdefs.Delete; 42 import org.apache.tools.ant.types.Description; 43 import org.apache.tools.ant.types.FileList; 44 import org.apache.tools.ant.types.FileSet; 45 import org.apache.tools.ant.types.Path; 46 import org.apache.tools.ant.types.PatternSet; 47 48 71 public class Launcher implements Runnable { 72 73 75 76 79 private static File bootstrapFile = null; 80 81 84 private static String javaCmd = null; 85 86 89 private static String jdbCmd = null; 90 91 94 private final static String DEFAULT_XML_FILE_NAME = "launcher.xml"; 95 96 99 private static Object lock = new Object (); 100 101 104 private static PrintStream log = System.err; 105 106 109 private static ResourceBundle resourceBundle = null; 110 111 114 private static boolean started = false; 115 116 119 private static boolean stopped = false; 120 121 124 public final static Object [] SUPPORTED_ANT_TASKS = new Object [] { 125 LaunchTask.TASK_NAME, LaunchTask.class, 126 "ant", Ant.class, 127 "antcall", CallTarget.class, 128 "available", Available.class, 129 "condition", ConditionTask.class, 130 "fail", Exit.class, 131 "property", Property.class, 132 "mkdir", Mkdir.class, 133 "delete", Delete.class, 134 "copy", Copy.class 135 }; 136 137 140 public final static Object [] SUPPORTED_ANT_TYPES = new Object [] { 141 ArgumentSet.TYPE_NAME, ArgumentSet.class, 142 JVMArgumentSet.TYPE_NAME, JVMArgumentSet.class, 143 SysPropertySet.TYPE_NAME, SysPropertySet.class, 144 "description", Description.class, 145 "fileset", FileSet.class, 146 "filelist", FileList.class, 147 "path", Path.class, 148 "patternset", PatternSet.class 149 }; 150 151 154 private static String toolsClasspath = null; 155 156 159 private static boolean verbose = false; 160 161 163 164 169 public static synchronized boolean isStarted() { 170 171 return Launcher.started; 172 173 } 174 175 180 public static synchronized boolean isStopped() { 181 182 return Launcher.stopped; 183 184 } 185 186 199 public static int start(String [] args) throws IllegalArgumentException { 200 201 synchronized (Launcher.lock) { 204 if (Launcher.isStarted() || Launcher.isStopped()) 205 return 1; 206 Launcher.setStarted(true); 207 } 208 209 int returnValue = 0; 210 ClassLoader parentLoader = null; 211 Thread shutdownHook = new Thread (new Launcher()); 212 Runtime runtime = Runtime.getRuntime(); 213 214 try { 215 216 parentLoader = Thread.currentThread().getContextClassLoader(); 221 boolean lessThan14 = true; 222 try { 223 Class.forName("java.lang.CharSequence"); 224 lessThan14 = false; 225 } catch (ClassNotFoundException cnfe) { 226 } 228 if (lessThan14) 229 Thread.currentThread().setContextClassLoader(Launcher.class.getClassLoader()); 230 231 Project project = new Project(); 232 233 project.setCoreLoader(Launcher.class.getClassLoader()); 235 236 for (int i = 0; i < Launcher.SUPPORTED_ANT_TASKS.length; i++) { 243 String taskName = (String )Launcher.SUPPORTED_ANT_TASKS[i]; 245 Class taskClass = (Class )Launcher.SUPPORTED_ANT_TASKS[++i]; 247 project.addTaskDefinition(taskName, taskClass); 248 } 249 for (int i = 0; i < Launcher.SUPPORTED_ANT_TYPES.length; i++) { 250 String typeName = (String )Launcher.SUPPORTED_ANT_TYPES[i]; 252 Class typeClass = (Class )Launcher.SUPPORTED_ANT_TYPES[++i]; 254 project.addDataTypeDefinition(typeName, typeClass); 255 } 256 257 project.setSystemProperties(); 259 260 int currentArg = 0; 262 263 File launchFile = new File (Launcher.getBootstrapDir(), Launcher.DEFAULT_XML_FILE_NAME); 265 266 for ( ; currentArg < args.length; currentArg++) { 268 if ("-".equals(args[currentArg])) { 271 currentArg++; 272 break; 273 } else if (args[currentArg].length() > 0 && !"-".equals(args[currentArg].substring(0, 1))) { 274 break; 275 } else if ("-help".equals(args[currentArg])) { 276 throw new IllegalArgumentException (); 277 } else if ("-launchfile".equals(args[currentArg])) { 278 if (currentArg + 1 < args.length){ 279 String fileArg = args[++currentArg]; 280 launchFile = new File (fileArg); 281 if (!launchFile.isAbsolute()) 282 launchFile = new File (Launcher.getBootstrapDir(), fileArg); 283 } else { 284 throw new IllegalArgumentException (args[currentArg] + " " + Launcher.getLocalizedString("missing.arg")); 285 } 286 } else if ("-executablename".equals(args[currentArg])) { 287 if (currentArg + 1 < args.length) 288 System.setProperty(ChildMain.EXECUTABLE_PROP_NAME, args[++currentArg]); 289 else 290 throw new IllegalArgumentException (args[currentArg] + " " + Launcher.getLocalizedString("missing.arg")); 291 } else if ("-verbose".equals(args[currentArg])) { 292 Launcher.setVerbose(true); 293 } else { 294 throw new IllegalArgumentException (args[currentArg] + " " + Launcher.getLocalizedString("invalid.arg")); 295 } 296 } 297 298 String target = null; 300 if (currentArg < args.length) 301 target = args[currentArg++]; 302 else 303 throw new IllegalArgumentException (Launcher.getLocalizedString("missing.target")); 304 305 for ( ; currentArg < args.length; currentArg++) { 307 if ("-".equals(args[currentArg])) { 310 currentArg++; 311 break; 312 } else if (args[currentArg].length() <= 2 || !"-D".equals(args[currentArg].substring(0, 2))) { 313 break; 314 } 315 int delimiter = args[currentArg].indexOf('=', 2); 316 String key = null; 317 String value = null; 318 if (delimiter >= 2) { 319 key = args[currentArg].substring(2, delimiter); 320 value = args[currentArg].substring(delimiter + 1); 321 } else { 322 key = args[currentArg].substring(2); 328 if (currentArg + 1 < args.length && 329 !"-D".equals(args[currentArg + 1].substring(0, 2))) 330 { 331 value = args[++currentArg]; 332 } else { 333 value = ""; 334 } 335 } 336 project.setUserProperty(key, value); 337 } 338 339 String [] appArgs = new String [args.length - currentArg]; 341 for (int i = 0; i < appArgs.length; i++) { 342 appArgs[i] = args[i + currentArg]; 343 project.setUserProperty(LaunchTask.ARG_PROP_NAME + Integer.toString(i), appArgs[i]); 344 } 345 346 project.setUserProperty("ant.version", Main.getAntVersion()); 348 project.setUserProperty("ant.file", launchFile.getCanonicalPath()); 349 project.setUserProperty("ant.java.version", System.getProperty("java.specification.version")); 350 351 ProjectHelper.configureProject(project, launchFile); 353 354 if (!project.getTargets().containsKey(target)) 356 throw new IllegalArgumentException (target + " " + Launcher.getLocalizedString("invalid.target")); 357 358 try { 360 runtime.addShutdownHook(shutdownHook); 361 } catch (NoSuchMethodError nsme) { 362 } 364 project.executeTarget(target); 365 366 } catch (Throwable t) { 367 returnValue = 1; 369 String message = t.getMessage(); 370 if (t instanceof IllegalArgumentException ) { 371 Launcher.error(message, true); 372 } else { 373 if (Launcher.verbose) 374 Launcher.error(t); 375 else 376 Launcher.error(message, false); 377 } 378 } finally { 379 synchronized (Launcher.lock) { 380 try { 382 runtime.removeShutdownHook(shutdownHook); 383 } catch (NoSuchMethodError nsme) { 384 } 386 Thread.currentThread().setContextClassLoader(parentLoader); 388 Launcher.setStarted(false); 390 Launcher.lock.notifyAll(); 392 } 393 } 394 395 Process [] childProcesses = LaunchTask.getChildProcesses(); 397 if (childProcesses.length > 0) 398 returnValue = childProcesses[childProcesses.length - 1].exitValue(); 399 400 return returnValue; 401 402 } 403 404 421 public static boolean stop() { 422 423 synchronized (Launcher.lock) { 424 if (Launcher.isStopped()) 427 return false; 428 429 if (Launcher.isStarted()) 432 Launcher.setStopped(true); 433 else 434 return false; 435 } 436 437 boolean returnValue = true; 438 439 try { 440 441 killChildProcesses(); 443 444 synchronized (Launcher.lock) { 446 if (Launcher.isStarted()) 447 Launcher.lock.wait(); 448 } 449 450 if (Launcher.isStarted()) 452 returnValue = true; 453 454 } catch (Throwable t) { 455 returnValue = false; 457 String message = t.getMessage(); 458 if (Launcher.verbose) 459 Launcher.error(t); 460 else 461 Launcher.error(message, false); 462 } finally { 463 Launcher.setStopped(false); 465 } 466 467 return returnValue; 468 469 } 470 471 477 public static void error(String message, boolean usage) { 478 479 if (message != null) 480 Launcher.getLog().println(Launcher.getLocalizedString("error") + ": " + message); 481 if (usage) 482 Launcher.getLog().println(Launcher.getLocalizedString("usage")); 483 484 } 485 486 491 public static void error(Throwable t) { 492 493 String message = t.getMessage(); 494 if (!Launcher.verbose && message != null) 495 Launcher.getLog().println(Launcher.getLocalizedString("error") + ": " + message); 496 else 497 t.printStackTrace(Launcher.getLog()); 498 499 } 500 501 511 public static File getBootstrapDir() throws IOException { 512 513 File file = Launcher.getBootstrapFile(); 514 if (file.isDirectory()) 515 return file; 516 else 517 return file.getParentFile(); 518 519 } 520 521 530 public static File getBootstrapFile() throws IOException { 531 532 if (bootstrapFile == null) { 533 534 String classResourceName = "/" + Launcher.class.getName().replace('.', '/') + ".class"; 536 URL resource = Launcher.class.getResource(classResourceName); 537 if (resource == null) 538 throw new IOException (Launcher.getLocalizedString("bootstrap.file.not.found") + ": " + Launcher.class.getName()); 539 String resourcePath = null; 540 String embeddedClassName = null; 541 boolean isJar = false; 542 String protocol = resource.getProtocol(); 543 if ((protocol != null) && 544 (protocol.indexOf("jar") >= 0)) { 545 isJar = true; 546 } 547 if (isJar) { 548 resourcePath = URLDecoder.decode(resource.getFile()); 549 embeddedClassName = "!" + classResourceName; 550 } else { 551 resourcePath = URLDecoder.decode(resource.toExternalForm()); 552 embeddedClassName = classResourceName; 553 } 554 int sep = resourcePath.lastIndexOf(embeddedClassName); 555 if (sep >= 0) 556 resourcePath = resourcePath.substring(0, sep); 557 558 if (resourcePath.indexOf("file:") == 0) 561 resourcePath = resourcePath.substring(5); 562 else 563 throw new IOException (Launcher.getLocalizedString("bootstrap.file.not.found") + ": " + Launcher.class.getName()); 564 565 File file = new File (resourcePath); 571 if (!file.exists() || !file.canRead()) 572 throw new IOException (Launcher.getLocalizedString("bootstrap.file.not.found") + ": " + Launcher.class.getName()); 573 bootstrapFile = file.getCanonicalFile(); 574 575 } 576 577 return bootstrapFile; 578 579 } 580 581 586 public static synchronized String getJavaCommand() { 587 588 if (javaCmd == null) { 589 590 String osname = System.getProperty("os.name").toLowerCase(); 591 String commandName = null; 592 if (osname.indexOf("windows") >= 0) { 593 commandName = "javaw.exe"; 596 } else { 597 commandName = "java"; 598 } 599 javaCmd = System.getProperty("java.home") + File.separator + "bin" + File.separator + commandName; 600 601 } 602 603 return javaCmd; 604 605 } 606 607 612 public static synchronized String getJDBCommand() { 613 614 if (jdbCmd == null) { 615 616 String osname = System.getProperty("os.name").toLowerCase(); 617 String commandName = null; 618 if (osname.indexOf("windows") >= 0) 619 commandName = "jdb.exe"; 620 else 621 commandName = "jdb"; 622 jdbCmd = new File (System.getProperty("java.home")).getParent() + File.separator + "bin" + File.separator + commandName; 623 624 } 625 626 return jdbCmd; 627 628 } 629 630 636 public static synchronized PrintStream getLog() { 637 638 return Launcher.log; 639 640 } 641 642 648 public static synchronized String getToolsClasspath() throws IOException { 649 650 if (toolsClasspath == null) { 651 652 File javaHome = null; 653 javaHome = new File (System.getProperty("java.home")).getCanonicalFile(); 654 Class clazz = null; 655 String [] toolsPaths = new String [2]; 656 toolsPaths[0] = javaHome.getParent() + File.separator + 657 "lib" + File.separator + "tools.jar"; 658 toolsPaths[1] = javaHome.getPath() + File.separator + 659 "lib" + File.separator + "tools.jar"; 660 File toolsFile = null; 661 for (int i = 0; i < toolsPaths.length; i++) { 662 ClassLoader loader = ClassLoader.getSystemClassLoader(); 663 toolsFile = new File (toolsPaths[i]); 664 if (!toolsFile.isFile() || !toolsFile.canRead()) 666 toolsFile = null; 667 if (toolsFile != null) { 668 try { 669 URL toolsURL = toolsFile.toURL(); 670 loader = new URLClassLoader (new URL []{toolsURL}, loader); 671 } catch (Exception e) { 672 toolsFile = null; 673 } 674 } 675 try { 680 clazz = loader.loadClass("sun.tools.javac.Main"); 681 if (clazz != null) 682 break; 683 } catch (Exception e) {} 684 } 685 686 if (clazz == null) 687 throw new IOException (Launcher.getLocalizedString("sdk.tools.not.found")); 688 689 if (toolsFile != null) 691 toolsClasspath = toolsFile.getPath(); 692 else 693 toolsClasspath = ""; 694 695 } 696 697 return toolsClasspath; 698 699 } 700 701 708 public static String getLocalizedString(String key) { 709 710 return Launcher.getLocalizedString(key, Launcher.class.getName()); 711 712 } 713 714 722 public static String getLocalizedString(String key, String className) { 723 724 try { 725 ResourceBundle resourceBundle = ResourceBundle.getBundle(className); 726 return Launcher.resolveString(resourceBundle.getString(key)); 727 } catch (Exception e) { 728 return "<" + key + " property>"; 731 } 732 733 } 734 735 756 private static String resolveString(String unresolved) throws IOException { 757 758 if (unresolved == null) 759 return null; 760 761 StringBuffer buf = new StringBuffer (); 763 int tokenEnd = 0; 764 int tokenStart = 0; 765 char token = '$'; 766 boolean escapeChar = false; 767 boolean firstToken = true; 768 boolean lastToken = false; 769 770 while (!lastToken) { 771 772 tokenEnd = unresolved.indexOf(token, tokenStart); 773 774 if (firstToken) { 776 firstToken = false; 777 if (tokenEnd - tokenStart == 0) { 779 tokenStart = ++tokenEnd; 780 continue; 781 } 782 } 783 if (tokenEnd < 0) { 785 lastToken = true; 786 tokenEnd = unresolved.length(); 787 } 788 789 if (escapeChar) { 790 791 buf.append(token + unresolved.substring(tokenStart, tokenEnd)); 793 escapeChar = !escapeChar; 794 795 } else { 796 797 int openProp = unresolved.indexOf('{', tokenStart); 799 int closeProp = unresolved.indexOf('}', tokenStart + 1); 800 String prop = null; 801 802 if (openProp != tokenStart || 805 closeProp < tokenStart + 1 || 806 closeProp >= tokenEnd) 807 { 808 buf.append(unresolved.substring(tokenStart, tokenEnd)); 809 } else { 810 String propName = unresolved.substring(tokenStart + 1, closeProp); 812 if ("launcher.executable.name".equals(propName)) { 813 prop = System.getProperty(ChildMain.EXECUTABLE_PROP_NAME); 814 if (prop != null) { 815 prop = "\"" + prop + "\""; 817 } else { 818 String classpath = Launcher.getBootstrapFile().getPath(); 820 prop = "\"" + System.getProperty("java.home") + File.separator + "bin" + File.separator + "java\" -classpath \"" + classpath + "\" LauncherBootstrap"; 821 } 822 } else if ("launcher.bootstrap.file".equals(propName)) { 823 prop = Launcher.getBootstrapFile().getPath(); 824 } else if ("launcher.bootstrap.dir".equals(propName)) { 825 prop = Launcher.getBootstrapDir().getPath(); 826 } else { 827 prop = System.getProperty(unresolved.substring(tokenStart + 1, closeProp)); 828 } 829 if (prop == null) 830 prop = ""; 831 buf.append(prop + unresolved.substring(++closeProp, tokenEnd)); 832 } 833 834 } 835 836 if (tokenEnd - tokenStart == 0) 840 escapeChar = !escapeChar; 841 842 tokenStart = ++tokenEnd; 843 844 } 845 846 return buf.toString(); 847 848 } 849 850 855 public static synchronized void setLog(PrintStream log) { 856 857 if (log != null) 858 Launcher.log = log; 859 else 860 Launcher.log = System.err; 861 862 } 863 864 869 private static synchronized void setStarted(boolean started) { 870 871 Launcher.started = started; 872 873 } 874 875 880 private static synchronized void setStopped(boolean stopped) { 881 882 Launcher.stopped = stopped; 883 884 } 885 886 891 public static synchronized void setVerbose(boolean verbose) { 892 893 Launcher.verbose = verbose; 894 895 } 896 897 901 public static void killChildProcesses() { 902 903 Process [] procs = LaunchTask.getChildProcesses(); 904 for (int i = 0; i < procs.length; i++) 905 procs[i].destroy(); 906 907 } 908 909 911 915 public void run() { 916 917 Launcher.killChildProcesses(); 918 919 } 920 921 } 922 | Popular Tags |