1 18 19 package org.apache.tools.ant.taskdefs; 20 21 import java.io.File ; 22 import java.io.IOException ; 23 import java.io.PrintWriter ; 24 import java.io.StringWriter ; 25 import java.util.Vector ; 26 import org.apache.tools.ant.BuildException; 27 import org.apache.tools.ant.ExitException; 28 import org.apache.tools.ant.Project; 29 import org.apache.tools.ant.Task; 30 import org.apache.tools.ant.ExitStatusException; 31 import org.apache.tools.ant.types.Commandline; 32 import org.apache.tools.ant.types.CommandlineJava; 33 import org.apache.tools.ant.types.Environment; 34 import org.apache.tools.ant.types.Path; 35 import org.apache.tools.ant.types.PropertySet; 36 import org.apache.tools.ant.types.Reference; 37 import org.apache.tools.ant.types.Assertions; 38 import org.apache.tools.ant.types.Permissions; 39 import org.apache.tools.ant.types.RedirectorElement; 40 import org.apache.tools.ant.taskdefs.condition.Os; 41 import org.apache.tools.ant.util.KeepAliveInputStream; 42 43 52 public class Java extends Task { 53 54 private CommandlineJava cmdl = new CommandlineJava(); 55 private Environment env = new Environment(); 56 private boolean fork = false; 57 private boolean newEnvironment = false; 58 private File dir = null; 59 private boolean failOnError = false; 60 private Long timeout = null; 61 62 private String inputString; 64 private File input; 65 private File output; 66 private File error; 67 68 protected Redirector redirector = new Redirector(this); 70 protected RedirectorElement redirectorElement; 71 73 private String resultProperty; 74 private Permissions perm = null; 75 76 private boolean spawn = false; 77 private boolean incompatibleWithSpawn = false; 78 79 82 public Java() { 83 } 84 85 89 public Java(Task owner) { 90 bindToOwner(owner); 91 } 92 93 98 public void execute() throws BuildException { 99 File savedDir = dir; 100 Permissions savedPermissions = perm; 101 102 int err = -1; 103 try { 104 err = executeJava(); 105 if (err != 0) { 106 if (failOnError) { 107 throw new ExitStatusException("Java returned: " + err, 108 err, 109 getLocation()); 110 } else { 111 log("Java Result: " + err, Project.MSG_ERR); 112 } 113 } 114 maybeSetResultPropertyValue(err); 115 } finally { 116 dir = savedDir; 117 perm = savedPermissions; 118 } 119 } 120 121 130 public int executeJava() throws BuildException { 131 String classname = getCommandLine().getClassname(); 132 if (classname == null && getCommandLine().getJar() == null) { 133 throw new BuildException("Classname must not be null."); 134 } 135 if (!fork && getCommandLine().getJar() != null) { 136 throw new BuildException("Cannot execute a jar in non-forked mode." 137 + " Please set fork='true'. "); 138 } 139 if (spawn && !fork) { 140 throw new BuildException("Cannot spawn a java process in non-forked mode." 141 + " Please set fork='true'. "); 142 } 143 if (getCommandLine().getClasspath() != null 144 && getCommandLine().getJar() != null) { 145 log("When using 'jar' attribute classpath-settings are ignored. " 146 + "See the manual for more information.", Project.MSG_VERBOSE); 147 } 148 if (spawn && incompatibleWithSpawn) { 149 getProject().log("spawn does not allow attributes related to input, " 150 + "output, error, result", Project.MSG_ERR); 151 getProject().log("spawn also does not allow timeout", Project.MSG_ERR); 152 getProject().log("finally, spawn is not compatible " 153 + "with a nested I/O <redirector>", Project.MSG_ERR); 154 throw new BuildException("You have used an attribute " 155 + "or nested element which is not compatible with spawn"); 156 } 157 if (getCommandLine().getAssertions() != null && !fork) { 158 log("Assertion statements are currently ignored in non-forked mode"); 159 } 160 if (fork) { 161 if (perm != null) { 162 log("Permissions can not be set this way in forked mode.", Project.MSG_WARN); 163 } 164 log(getCommandLine().describeCommand(), Project.MSG_VERBOSE); 165 } else { 166 if (getCommandLine().getVmCommand().size() > 1) { 167 log("JVM args ignored when same JVM is used.", 168 Project.MSG_WARN); 169 } 170 if (dir != null) { 171 log("Working directory ignored when same JVM is used.", 172 Project.MSG_WARN); 173 } 174 if (newEnvironment || null != env.getVariables()) { 175 log("Changes to environment variables are ignored when same " 176 + "JVM is used.", Project.MSG_WARN); 177 } 178 if (getCommandLine().getBootclasspath() != null) { 179 log("bootclasspath ignored when same JVM is used.", 180 Project.MSG_WARN); 181 } 182 if (perm == null) { 183 perm = new Permissions(true); 184 log("running " + this.getCommandLine().getClassname() 185 + " with default permissions (exit forbidden)", Project.MSG_VERBOSE); 186 } 187 log("Running in same VM " + getCommandLine().describeJavaCommand(), 188 Project.MSG_VERBOSE); 189 } 190 setupRedirector(); 191 try { 192 if (fork) { 193 if (!spawn) { 194 return fork(getCommandLine().getCommandline()); 195 } else { 196 spawn(getCommandLine().getCommandline()); 197 return 0; 198 } 199 } else { 200 try { 201 run(getCommandLine()); 202 return 0; 203 } catch (ExitException ex) { 204 return ex.getStatus(); 205 } 206 } 207 } catch (BuildException e) { 208 if (e.getLocation() == null && getLocation() != null) { 209 e.setLocation(getLocation()); 210 } 211 if (failOnError) { 212 throw e; 213 } else { 214 log(e); 215 return 0; 216 } 217 } catch (ThreadDeath t) { 218 throw t; } catch (Throwable t) { 220 if (failOnError) { 221 throw new BuildException(t, getLocation()); 222 } else { 223 log(t); 224 return 0; 225 } 226 } 227 } 228 229 235 public void setSpawn(boolean spawn) { 236 this.spawn = spawn; 237 } 238 239 244 public void setClasspath(Path s) { 245 createClasspath().append(s); 246 } 247 248 253 public Path createClasspath() { 254 return getCommandLine().createClasspath(getProject()).createPath(); 255 } 256 257 263 public Path createBootclasspath() { 264 return getCommandLine().createBootclasspath(getProject()).createPath(); 265 } 266 267 272 public Permissions createPermissions() { 273 perm = (perm == null) ? new Permissions() : perm; 274 return perm; 275 } 276 277 282 public void setClasspathRef(Reference r) { 283 createClasspath().setRefid(r); 284 } 285 286 293 public void setJar(File jarfile) throws BuildException { 294 if (getCommandLine().getClassname() != null) { 295 throw new BuildException("Cannot use 'jar' and 'classname' " 296 + "attributes in same command."); 297 } 298 getCommandLine().setJar(jarfile.getAbsolutePath()); 299 } 300 301 308 public void setClassname(String s) throws BuildException { 309 if (getCommandLine().getJar() != null) { 310 throw new BuildException("Cannot use 'jar' and 'classname' " 311 + "attributes in same command"); 312 } 313 getCommandLine().setClassname(s); 314 } 315 316 324 public void setArgs(String s) { 325 log("The args attribute is deprecated. " 326 + "Please use nested arg elements.", Project.MSG_WARN); 327 getCommandLine().createArgument().setLine(s); 328 } 329 330 339 public void setCloneVm(boolean cloneVm) { 340 getCommandLine().setCloneVm(cloneVm); 341 } 342 343 348 public Commandline.Argument createArg() { 349 return getCommandLine().createArgument(); 350 } 351 352 360 public void setResultProperty(String resultProperty) { 361 this.resultProperty = resultProperty; 362 incompatibleWithSpawn = true; 363 } 364 365 371 protected void maybeSetResultPropertyValue(int result) { 372 String res = Integer.toString(result); 373 if (resultProperty != null) { 374 getProject().setNewProperty(resultProperty, res); 375 } 376 } 377 378 383 public void setFork(boolean s) { 384 this.fork = s; 385 } 386 387 392 public void setJvmargs(String s) { 393 log("The jvmargs attribute is deprecated. " 394 + "Please use nested jvmarg elements.", Project.MSG_WARN); 395 getCommandLine().createVmArgument().setLine(s); 396 } 397 398 403 public Commandline.Argument createJvmarg() { 404 return getCommandLine().createVmArgument(); 405 } 406 407 412 public void setJvm(String s) { 413 getCommandLine().setVm(s); 414 } 415 416 421 public void addSysproperty(Environment.Variable sysp) { 422 getCommandLine().addSysproperty(sysp); 423 } 424 425 432 public void addSyspropertyset(PropertySet sysp) { 433 getCommandLine().addSyspropertyset(sysp); 434 } 435 436 443 public void setFailonerror(boolean fail) { 444 failOnError = fail; 445 incompatibleWithSpawn |= fail; 446 } 447 448 454 public void setDir(File d) { 455 this.dir = d; 456 } 457 458 463 public void setOutput(File out) { 464 this.output = out; 465 incompatibleWithSpawn = true; 466 } 467 468 473 public void setInput(File input) { 474 if (inputString != null) { 475 throw new BuildException("The \"input\" and \"inputstring\" " 476 + "attributes cannot both be specified"); 477 } 478 this.input = input; 479 incompatibleWithSpawn = true; 480 } 481 482 487 public void setInputString(String inputString) { 488 if (input != null) { 489 throw new BuildException("The \"input\" and \"inputstring\" " 490 + "attributes cannot both be specified"); 491 } 492 this.inputString = inputString; 493 incompatibleWithSpawn = true; 494 } 495 496 504 public void setLogError(boolean logError) { 505 redirector.setLogError(logError); 506 incompatibleWithSpawn |= logError; 507 } 508 509 516 public void setError(File error) { 517 this.error = error; 518 incompatibleWithSpawn = true; 519 } 520 521 528 public void setOutputproperty(String outputProp) { 529 redirector.setOutputProperty(outputProp); 530 incompatibleWithSpawn = true; 531 } 532 533 541 public void setErrorProperty(String errorProperty) { 542 redirector.setErrorProperty(errorProperty); 543 incompatibleWithSpawn = true; 544 } 545 546 551 public void setMaxmemory(String max) { 552 getCommandLine().setMaxmemory(max); 553 } 554 555 559 public void setJVMVersion(String value) { 560 getCommandLine().setVmversion(value); 561 } 562 563 572 public void addEnv(Environment.Variable var) { 573 env.addVariable(var); 574 } 575 576 585 public void setNewenvironment(boolean newenv) { 586 newEnvironment = newenv; 587 } 588 589 596 public void setAppend(boolean append) { 597 redirector.setAppend(append); 598 incompatibleWithSpawn = true; 599 } 600 601 608 public void setTimeout(Long value) { 609 timeout = value; 610 incompatibleWithSpawn |= timeout != null; 611 } 612 613 618 public void addAssertions(Assertions asserts) { 619 if (getCommandLine().getAssertions() != null) { 620 throw new BuildException("Only one assertion declaration is allowed"); 621 } 622 getCommandLine().setAssertions(asserts); 623 } 624 625 629 public void addConfiguredRedirector(RedirectorElement redirectorElement) { 630 if (this.redirectorElement != null) { 631 throw new BuildException("cannot have > 1 nested redirectors"); 632 } 633 this.redirectorElement = redirectorElement; 634 incompatibleWithSpawn = true; 635 } 636 637 644 protected void handleOutput(String output) { 645 if (redirector.getOutputStream() != null) { 646 redirector.handleOutput(output); 647 } else { 648 super.handleOutput(output); 649 } 650 } 651 652 664 public int handleInput(byte[] buffer, int offset, int length) 665 throws IOException { 666 return redirector.handleInput(buffer, offset, length); 668 } 669 670 677 protected void handleFlush(String output) { 678 if (redirector.getOutputStream() != null) { 679 redirector.handleFlush(output); 680 } else { 681 super.handleFlush(output); 682 } 683 } 684 685 692 protected void handleErrorOutput(String output) { 693 if (redirector.getErrorStream() != null) { 694 redirector.handleErrorOutput(output); 695 } else { 696 super.handleErrorOutput(output); 697 } 698 } 699 700 707 protected void handleErrorFlush(String output) { 708 if (redirector.getErrorStream() != null) { 709 redirector.handleErrorFlush(output); 710 } else { 711 super.handleErrorOutput(output); 712 } 713 } 714 715 718 protected void setupRedirector() { 719 redirector.setInput(input); 720 redirector.setInputString(inputString); 721 redirector.setOutput(output); 722 redirector.setError(error); 723 if (redirectorElement != null) { 724 redirectorElement.configure(redirector); 725 } 726 if (!spawn && input == null && inputString == null) { 727 redirector.setInputStream( 729 new KeepAliveInputStream(getProject().getDefaultInputStream())); 730 } 731 } 732 733 738 private void run(CommandlineJava command) throws BuildException { 739 try { 740 ExecuteJava exe = new ExecuteJava(); 741 exe.setJavaCommand(command.getJavaCommand()); 742 exe.setClasspath(command.getClasspath()); 743 exe.setSystemProperties(command.getSystemProperties()); 744 exe.setPermissions(perm); 745 exe.setTimeout(timeout); 746 redirector.createStreams(); 747 exe.execute(getProject()); 748 redirector.complete(); 749 if (exe.killedProcess()) { 750 throw new BuildException("Timeout: killed the sub-process"); 751 } 752 } catch (IOException e) { 753 throw new BuildException(e); 754 } 755 } 756 757 761 private int fork(String [] command) throws BuildException { 762 Execute exe 763 = new Execute(redirector.createHandler(), createWatchdog()); 764 setupExecutable(exe, command); 765 766 try { 767 int rc = exe.execute(); 768 redirector.complete(); 769 if (exe.killedProcess()) { 770 throw new BuildException("Timeout: killed the sub-process"); 771 } 772 return rc; 773 } catch (IOException e) { 774 throw new BuildException(e, getLocation()); 775 } 776 } 777 778 782 private void spawn(String [] command) throws BuildException { 783 Execute exe = new Execute(); 784 setupExecutable(exe, command); 785 try { 786 exe.spawn(); 787 } catch (IOException e) { 788 throw new BuildException(e, getLocation()); 789 } 790 } 791 792 799 private void setupExecutable(Execute exe, String [] command) { 800 exe.setAntRun(getProject()); 801 setupWorkingDir(exe); 802 setupEnvironment(exe); 803 setupCommandLine(exe, command); 804 } 805 806 810 private void setupEnvironment(Execute exe) { 811 String [] environment = env.getVariables(); 812 if (environment != null) { 813 for (int i = 0; i < environment.length; i++) { 814 log("Setting environment variable: " + environment[i], 815 Project.MSG_VERBOSE); 816 } 817 } 818 exe.setNewenvironment(newEnvironment); 819 exe.setEnvironment(environment); 820 } 821 822 827 private void setupWorkingDir(Execute exe) { 828 if (dir == null) { 829 dir = getProject().getBaseDir(); 830 } else if (!dir.exists() || !dir.isDirectory()) { 831 throw new BuildException(dir.getAbsolutePath() 832 + " is not a valid directory", 833 getLocation()); 834 } 835 exe.setWorkingDirectory(dir); 836 } 837 838 844 private void setupCommandLine(Execute exe, String [] command) { 845 if (Os.isFamily("openvms")) { 849 setupCommandLineForVMS(exe, command); 850 } else { 851 exe.setCommandline(command); 852 } 853 } 854 855 863 private void setupCommandLineForVMS(Execute exe, String [] command) { 864 ExecuteJava.setupCommandLineForVMS(exe, command); 865 } 866 867 875 protected void run(String classname, Vector args) throws BuildException { 876 CommandlineJava cmdj = new CommandlineJava(); 877 cmdj.setClassname(classname); 878 for (int i = 0; i < args.size(); i++) { 879 cmdj.createArgument().setValue((String ) args.elementAt(i)); 880 } 881 run(cmdj); 882 } 883 884 887 public void clearArgs() { 888 getCommandLine().clearJavaArgs(); 889 } 890 891 900 protected ExecuteWatchdog createWatchdog() throws BuildException { 901 if (timeout == null) { 902 return null; 903 } 904 return new ExecuteWatchdog(timeout.longValue()); 905 } 906 907 912 private void log(Throwable t) { 913 StringWriter sw = new StringWriter (); 914 PrintWriter w = new PrintWriter (sw); 915 t.printStackTrace(w); 916 w.close(); 917 log(sw.toString(), Project.MSG_ERR); 918 } 919 920 926 public CommandlineJava getCommandLine() { 927 return cmdl; 928 } 929 930 936 public CommandlineJava.SysProperties getSysProperties() { 937 return getCommandLine().getSystemProperties(); 938 } 939 } 940 | Popular Tags |