1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.launcher;
19
20 import java.io.File;
21 import java.io.FileOutputStream;
22 import java.io.IOException;
23 import java.net.URL;
24 import java.net.URLClassLoader;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.StringTokenizer;
29 import org.apache.commons.launcher.types.ArgumentSet;
30 import org.apache.commons.launcher.types.ConditionalArgument;
31 import org.apache.commons.launcher.types.ConditionalVariable;
32 import org.apache.commons.launcher.types.JVMArgumentSet;
33 import org.apache.commons.launcher.types.SysPropertySet;
34 import org.apache.tools.ant.BuildException;
35 import org.apache.tools.ant.Task;
36 import org.apache.tools.ant.types.Path;
37 import org.apache.tools.ant.types.Reference;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 public class LaunchTask extends Task {
64
65
66
67
68
69
70 public final static String ARG_PROP_NAME = "launch.arg.";
71
72
73
74
75 public final static String TASK_NAME = "launch";
76
77
78
79
80 private static ArrayList childProcesses = new ArrayList();
81
82
83
84
85
86
87 private boolean appendOutput = false;
88
89
90
91
92 private Process childProc = null;
93
94
95
96
97 private Path classpath = null;
98
99
100
101
102 private boolean debug = false;
103
104
105
106
107 private boolean displayMinimizedWindow = false;
108
109
110
111
112 private boolean disposeMinimizedWindow = true;
113
114
115
116
117 private boolean failOnError = false;
118
119
120
121
122 private LaunchFilter filter = null;
123
124
125
126
127 private String filterClassName = null;
128
129
130
131
132 private Path filterClasspath = null;
133
134
135
136
137 private String mainClassName = null;
138
139
140
141
142 private File minimizedWindowIcon = null;
143
144
145
146
147 private String minimizedWindowTitle = null;
148
149
150
151
152 private File outputFile = null;
153
154
155
156
157 private boolean print = false;
158
159
160
161
162 private boolean redirect = false;
163
164
165
166
167 private boolean requireTools = false;
168
169
170
171
172 private ArgumentSet taskArgumentSet = new ArgumentSet();
173
174
175
176
177 private JVMArgumentSet taskJVMArgumentSet = new JVMArgumentSet();
178
179
180
181
182 private SysPropertySet taskSysPropertySet = new SysPropertySet();
183
184
185
186
187 private boolean useArgs = true;
188
189
190
191
192 private boolean useSystemIn = true;
193
194
195
196
197 private boolean waitForChild = true;
198
199
200
201
202
203
204
205
206 public static Process[] getChildProcesses() {
207
208 return (Process[])childProcesses.toArray(new Process[childProcesses.size()]);
209
210 }
211
212
213
214
215
216
217
218
219
220
221
222 public void addArg(ConditionalArgument arg) {
223
224 taskArgumentSet.addArg(arg);
225
226 }
227
228
229
230
231
232
233 public void addArgset(ArgumentSet set) {
234
235 taskArgumentSet.addArgset(set);
236
237 }
238
239
240
241
242
243
244
245
246
247 public void addJvmarg(ConditionalArgument jvmArg) {
248
249 taskJVMArgumentSet.addJvmarg(jvmArg);
250
251 }
252
253
254
255
256
257
258 public void addJvmargset(JVMArgumentSet set) {
259
260 taskJVMArgumentSet.addJvmargset(set);
261
262 }
263
264
265
266
267
268
269
270
271
272 public void addSysproperty(ConditionalVariable var) {
273
274 taskSysPropertySet.addSysproperty(var);
275
276 }
277
278
279
280
281
282
283 public void addSyspropertyset(SysPropertySet set) {
284
285 taskSysPropertySet.addSyspropertyset(set);
286
287 }
288
289
290
291
292
293
294 public Path createClasspath() {
295
296 if (classpath == null)
297 classpath = new Path(project);
298 return classpath;
299
300 }
301
302
303
304
305
306
307
308 public Path createFilterclasspath() {
309
310 if (filterClasspath == null)
311 filterClasspath = new Path(project);
312 return filterClasspath;
313
314 }
315
316
317
318
319
320
321
322
323 public void execute() throws BuildException {
324
325 try {
326
327
328
329 if (!Launcher.isStarted())
330 throw new BuildException(Launcher.getLocalizedString("no.run.standalone", this.getClass().getName()));
331
332
333 if (Launcher.isStopped())
334 throw new BuildException();
335
336 if (mainClassName == null)
337 throw new BuildException(Launcher.getLocalizedString("classname.null", this.getClass().getName()));
338
339
340 ArrayList taskJVMArgs = taskJVMArgumentSet.getList();
341 ArrayList jvmArgs = new ArrayList(taskJVMArgs.size());
342 for (int i = 0; i < taskJVMArgs.size(); i++) {
343 ConditionalArgument value = (ConditionalArgument)taskJVMArgs.get(i);
344
345 if (testIfCondition(value.getIf()) && testUnlessCondition(value.getUnless())) {
346 String[] list = value.getParts();
347 for (int j = 0; j < list.length; j++)
348 jvmArgs.add(list[j]);
349 }
350 }
351
352
353
354 ArrayList taskSysProps = taskSysPropertySet.getList();
355 HashMap sysProps = new HashMap(taskSysProps.size());
356 for (int i = 0; i < taskSysProps.size(); i++) {
357 ConditionalVariable variable = (ConditionalVariable)taskSysProps.get(i);
358
359 if (testIfCondition(variable.getIf()) && testUnlessCondition(variable.getUnless()))
360 sysProps.put(variable.getKey(), variable.getValue());
361 }
362
363
364 ArrayList taskArgs = taskArgumentSet.getList();
365 ArrayList appArgs = new ArrayList(taskArgs.size());
366 for (int i = 0; i < taskArgs.size(); i++) {
367 ConditionalArgument value = (ConditionalArgument)taskArgs.get(i);
368
369 if (testIfCondition(value.getIf()) && testUnlessCondition(value.getUnless())) {
370 String[] list = value.getParts();
371 for (int j = 0; j < list.length; j++)
372 appArgs.add(list[j]);
373 }
374 }
375
376
377 if (useArgs) {
378 int currentArg = 0;
379 String arg = null;
380 while ((arg = project.getUserProperty(LaunchTask.ARG_PROP_NAME + Integer.toString(currentArg++))) != null)
381 appArgs.add(arg);
382 }
383
384
385
386 String filteredClasspath = null;
387 if (classpath != null)
388 filteredClasspath = classpath.toString();
389 String filteredMainClassName = mainClassName;
390 boolean filteredRedirect = redirect;
391 File filteredOutputFile = outputFile;
392 boolean filteredAppendOutput = appendOutput;
393 boolean filteredDebug = debug;
394 boolean filteredDisplayMinimizedWindow = displayMinimizedWindow;
395 boolean filteredDisposeMinimizedWindow = disposeMinimizedWindow;
396 boolean filteredFailOnError = failOnError;
397 String filteredMinimizedWindowTitle = minimizedWindowTitle;
398 File filteredMinimizedWindowIcon = minimizedWindowIcon;
399 boolean filteredPrint = print;
400 boolean filteredRequireTools = requireTools;
401 boolean filteredUseSystemIn = useSystemIn;
402 boolean filteredWaitForChild = waitForChild;
403
404
405
406
407 if (filterClassName != null) {
408 if (filter == null) {
409 try {
410 ClassLoader loader = this.getClass().getClassLoader();
411 if (filterClasspath != null) {
412
413 String[] fileList = filterClasspath.list();
414 URL[] urls = new URL[fileList.length];
415 for (int i = 0; i < fileList.length; i++)
416 urls[i] = new File(fileList[i]).toURL();
417 loader = new URLClassLoader(urls, loader);
418 }
419 Class filterClass = loader.loadClass(filterClassName);
420 filter = (LaunchFilter)filterClass.newInstance();
421
422 LaunchCommand command = new LaunchCommand();
423 command.setJvmargs(jvmArgs);
424 command.setSysproperties(sysProps);
425 command.setArgs(appArgs);
426 command.setClasspath(filteredClasspath);
427 command.setClassname(filteredMainClassName);
428 command.setRedirectoutput(filteredRedirect);
429 command.setOutput(filteredOutputFile);
430 command.setAppendoutput(filteredAppendOutput);
431 command.setDebug(filteredDebug);
432 command.setDisplayminimizedwindow(filteredDisplayMinimizedWindow);
433 command.setDisposeminimizedwindow(filteredDisposeMinimizedWindow);
434 command.setFailonerror(filteredFailOnError);
435 command.setMinimizedwindowtitle(filteredMinimizedWindowTitle);
436 command.setMinimizedwindowicon(filteredMinimizedWindowIcon);
437 command.setPrint(filteredPrint);
438 command.setRequiretools(filteredRequireTools);
439 command.setUsesystemin(filteredUseSystemIn);
440 command.setWaitforchild(filteredWaitForChild);
441 filter.filter(command);
442 jvmArgs = command.getJvmargs();
443 sysProps = command.getSysproperties();
444 appArgs = command.getArgs();
445 filteredClasspath = command.getClasspath();
446 filteredMainClassName = command.getClassname();
447 filteredRedirect = command.getRedirectoutput();
448 filteredOutputFile = command.getOutput();
449 filteredAppendOutput = command.getAppendoutput();
450 filteredDebug = command.getDebug();
451 filteredDisplayMinimizedWindow = command.getDisplayminimizedwindow();
452 filteredDisposeMinimizedWindow = command.getDisposeminimizedwindow();
453 filteredFailOnError = command.getFailonerror();
454 filteredMinimizedWindowTitle = command.getMinimizedwindowtitle();
455 filteredMinimizedWindowIcon = command.getMinimizedwindowicon();
456 filteredPrint = command.getPrint();
457 filteredRequireTools = command.getRequiretools();
458 filteredUseSystemIn = command.getUsesystemin();
459 filteredWaitForChild = command.getWaitforchild();
460
461 if (filteredMainClassName == null)
462 throw new BuildException(Launcher.getLocalizedString("classname.null", this.getClass().getName()));
463 if (jvmArgs == null)
464 jvmArgs = new ArrayList();
465 if (sysProps == null)
466 sysProps = new HashMap();
467 if (appArgs == null)
468 appArgs = new ArrayList();
469 } catch (BuildException be) {
470 throw new BuildException(filterClassName + " " + Launcher.getLocalizedString("filter.exception", this.getClass().getName()), be);
471 } catch (ClassCastException cce) {
472 throw new BuildException(filterClassName + " " + Launcher.getLocalizedString("filter.not.filter", this.getClass().getName()));
473 } catch (Exception e) {
474 throw new BuildException(e);
475 }
476 }
477 }
478
479
480 if (filteredDebug) {
481 filteredWaitForChild = true;
482 filteredUseSystemIn = true;
483 }
484
485
486 StringBuffer fullClasspath = new StringBuffer(Launcher.getBootstrapFile().getPath());
487 if (filteredRequireTools) {
488 fullClasspath.append(File.pathSeparator);
489 fullClasspath.append(Launcher.getToolsClasspath());
490 }
491 if (filteredClasspath != null) {
492 fullClasspath.append(File.pathSeparator);
493 fullClasspath.append(filteredClasspath);
494 }
495
496
497 sysProps.remove(ChildMain.WAIT_FOR_CHILD_PROP_NAME);
498 if (filteredWaitForChild)
499 sysProps.put(ChildMain.WAIT_FOR_CHILD_PROP_NAME, "");
500
501
502 sysProps.remove(ChildMain.DISPLAY_MINIMIZED_WINDOW_PROP_NAME);
503 sysProps.remove(ChildMain.MINIMIZED_WINDOW_TITLE_PROP_NAME);
504 sysProps.remove(ChildMain.MINIMIZED_WINDOW_ICON_PROP_NAME);
505 sysProps.remove(ChildMain.DISPOSE_MINIMIZED_WINDOW_PROP_NAME);
506 if (!filteredWaitForChild && filteredDisplayMinimizedWindow) {
507 sysProps.put(ChildMain.DISPLAY_MINIMIZED_WINDOW_PROP_NAME, "");
508 if (filteredMinimizedWindowTitle != null)
509 sysProps.put(ChildMain.MINIMIZED_WINDOW_TITLE_PROP_NAME, filteredMinimizedWindowTitle);
510 else
511 sysProps.put(ChildMain.MINIMIZED_WINDOW_TITLE_PROP_NAME, getOwningTarget().getName());
512 if (filteredMinimizedWindowIcon != null)
513 sysProps.put(ChildMain.MINIMIZED_WINDOW_ICON_PROP_NAME, filteredMinimizedWindowIcon.getCanonicalPath());
514
515 if (filteredDisposeMinimizedWindow)
516 sysProps.put(ChildMain.DISPOSE_MINIMIZED_WINDOW_PROP_NAME, "");
517 }
518
519
520 sysProps.remove(ChildMain.OUTPUT_FILE_PROP_NAME);
521 if (!filteredWaitForChild && filteredRedirect) {
522 if (filteredOutputFile != null) {
523 String outputFilePath = filteredOutputFile.getCanonicalPath();
524
525 try {
526 File parentFile = new File(filteredOutputFile.getParent());
527
528 if ( !parentFile.exists() ) {
529
530 parentFile.mkdirs();
531
532
533 }
534 filteredOutputFile.createNewFile();
535 } catch (IOException ioe) {
536 throw new BuildException(outputFilePath + " " + Launcher.getLocalizedString("output.file.not.creatable", this.getClass().getName()));
537 }
538 if (!filteredOutputFile.canWrite())
539 throw new BuildException(outputFilePath + " " + Launcher.getLocalizedString("output.file.not.writable", this.getClass().getName()));
540 sysProps.put(ChildMain.OUTPUT_FILE_PROP_NAME, outputFilePath);
541 if (filteredAppendOutput)
542 sysProps.put(ChildMain.APPEND_OUTPUT_PROP_NAME, "");
543 Launcher.getLog().println(Launcher.getLocalizedString("redirect.notice", this.getClass().getName()) + " " + outputFilePath);
544 } else {
545 throw new BuildException(Launcher.getLocalizedString("output.file.null", this.getClass().getName()));
546 }
547 }
548
549
550
551
552
553 File heartbeatFile = null;
554 FileOutputStream heartbeatOutputStream = null;
555 if (filteredWaitForChild) {
556 File tmpDir = null;
557 String tmpDirName = (String)sysProps.get("java.io.tmpdir");
558 if (tmpDirName != null)
559 tmpDir = new File(tmpDirName);
560 heartbeatFile = File.createTempFile(ChildMain.HEARTBEAT_FILE_PROP_NAME + ".", "", tmpDir);
561
562
563 heartbeatOutputStream = new FileOutputStream(heartbeatFile);
564 sysProps.put(ChildMain.HEARTBEAT_FILE_PROP_NAME, heartbeatFile.getCanonicalPath());
565 }
566
567
568 String[] cmd = new String[5 + jvmArgs.size() + sysProps.size() + appArgs.size()];
569 int nextCmdArg = 0;
570 if (filteredDebug)
571 cmd[nextCmdArg++] = Launcher.getJDBCommand();
572 else
573 cmd[nextCmdArg++] = Launcher.getJavaCommand();
574
575 for (int i = 0; i < jvmArgs.size(); i++)
576 cmd[nextCmdArg++] = (String)jvmArgs.get(i);
577
578 Iterator sysPropsKeys = sysProps.keySet().iterator();
579 while (sysPropsKeys.hasNext()) {
580 String key = (String)sysPropsKeys.next();
581 if (key == null)
582 continue;
583 String value = (String)sysProps.get(key);
584 if (value == null)
585 value = "";
586 cmd[nextCmdArg++] = "-D" + key + "=" + value;
587 }
588
589
590
591 cmd[nextCmdArg++] = "-classpath";
592 cmd[nextCmdArg++] = fullClasspath.toString();
593
594 int mainClassArg = nextCmdArg;
595 cmd[nextCmdArg++] = ChildMain.class.getName();
596 cmd[nextCmdArg++] = filteredMainClassName;
597
598 for (int i = 0; i < appArgs.size(); i++)
599 {
600 cmd[nextCmdArg++] = (String)appArgs.get(i);
601 }
602
603 if (filteredPrint) {
604
605 String osname = System.getProperty("os.name").toLowerCase();
606 StringBuffer buf = new StringBuffer(cmd.length * 100);
607 String quote = null;
608 String replaceQuote = null;
609 if (osname.indexOf("windows") >= 0) {
610
611 quote = "\"";
612 replaceQuote = quote + quote + quote;
613 } else {
614
615 quote = "'";
616 replaceQuote = quote + "\\" + quote + quote;
617 }
618 for (int i = 0; i < cmd.length; i++) {
619
620
621 if (i == mainClassArg)
622 continue;
623 if (i > 0)
624 buf.append(" ");
625 buf.append(quote);
626 StringTokenizer tokenizer = new StringTokenizer(cmd[i], quote, true);
627 while (tokenizer.hasMoreTokens()) {
628 String token = tokenizer.nextToken();
629 if (quote.equals(token))
630 buf.append(replaceQuote);
631 else
632 buf.append(token);
633 }
634 buf.append(quote);
635 }
636
637 System.err.println(Launcher.getLocalizedString("executing.child.command", this.getClass().getName()) + ":");
638 System.err.println(buf.toString());
639 }
640
641
642 if (Launcher.isStopped())
643 throw new BuildException();
644 Process proc = null;
645 synchronized (LaunchTask.childProcesses) {
646 proc = Runtime.getRuntime().exec(cmd);
647
648 if (filteredWaitForChild) {
649 childProc = proc;
650 LaunchTask.childProcesses.add(proc);
651 }
652 }
653 if (filteredWaitForChild) {
654 StreamConnector stdout =
655 new StreamConnector(proc.getInputStream(), System.out);
656 StreamConnector stderr =
657 new StreamConnector(proc.getErrorStream(), System.err);
658 stdout.start();
659 stderr.start();
660 if (filteredUseSystemIn) {
661 StreamConnector stdin =
662 new StreamConnector(System.in, proc.getOutputStream());
663 stdin.start();
664 }
665 proc.waitFor();
666
667 stdout.join();
668 stderr.join();
669 if (heartbeatOutputStream != null)
670 heartbeatOutputStream.close();
671 if (heartbeatFile != null)
672 heartbeatFile.delete();
673 int exitValue = proc.exitValue();
674 if (filteredFailOnError && exitValue != 0)
675 throw new BuildException(Launcher.getLocalizedString("child.failed", this.getClass().getName()) + " " + exitValue);
676 }
677
678
679 if (Launcher.isStopped())
680 throw new BuildException();
681
682 } catch (BuildException be) {
683 throw be;
684 } catch (Exception e) {
685 if (Launcher.isStopped())
686 throw new BuildException(Launcher.getLocalizedString("launch.task.stopped", this.getClass().getName()));
687 else
688 throw new BuildException(e);
689 }
690
691 }
692
693
694
695
696
697
698
699
700
701 public void setUseargs(boolean useArgs) {
702
703 this.useArgs = useArgs;
704
705 }
706
707
708
709
710
711
712
713
714
715
716 public void setUsesystemin(boolean useSystemIn) {
717
718 this.useSystemIn = useSystemIn;
719
720 }
721
722
723
724
725
726
727
728
729
730
731
732 public void setWaitforchild(boolean waitForChild) {
733
734 this.waitForChild = waitForChild;
735
736 }
737
738
739
740
741
742
743 public void setClassname(String mainClassName) {
744
745 this.mainClassName = mainClassName;
746
747 }
748
749
750
751
752
753
754 public void setClasspath(Path classpath) {
755
756 createClasspath().append(classpath);
757
758 }
759
760
761
762
763
764
765 public void setClasspathref(Reference ref) {
766
767 createClasspath().setRefid(ref);
768
769 }
770
771
772
773
774
775
776
777 public void setDebug(boolean debug) {
778
779 this.debug = debug;
780
781 }
782
783
784
785
786
787
788
789
790
791
792
793
794 public void setDisplayminimizedwindow(boolean displayMinimizedWindow) {
795
796 this.displayMinimizedWindow = displayMinimizedWindow;
797
798 }
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816 public void setDisposeminimizedwindow(boolean disposeMinimizedWindow) {
817
818 this.disposeMinimizedWindow = disposeMinimizedWindow;
819
820 }
821
822
823
824
825
826
827
828 public void setFailonerror(boolean failOnError) {
829
830 this.failOnError = failOnError;
831
832 }
833
834
835
836
837
838
839 public void setFilterclassname(String filterClassName) {
840
841 this.filterClassName = filterClassName;
842
843 }
844
845
846
847
848
849
850 public void setFilterclasspath(Path filterClasspath) {
851
852 createFilterclasspath().append(filterClasspath);
853
854 }
855
856
857
858
859
860
861
862
863
864 public void setMinimizedwindowtitle(String minimizedWindowTitle) {
865
866 this.minimizedWindowTitle = minimizedWindowTitle;
867
868 }
869
870
871
872
873
874
875
876
877
878 public void setMinimizedwindowicon(File minimizedWindowIcon) {
879
880 this.minimizedWindowIcon = minimizedWindowIcon;
881
882 }
883
884
885
886
887
888
889
890
891 public void setOutput(File outputFile) {
892
893 this.outputFile = outputFile;
894
895 }
896
897
898
899
900
901
902
903 public void setPrint(boolean print) {
904
905 this.print = print;
906
907 }
908
909
910
911
912
913
914
915
916
917 public void setAppendoutput(boolean appendOutput) {
918
919 this.appendOutput = appendOutput;
920
921 }
922
923
924
925
926
927
928
929
930
931 public void setRedirectoutput(boolean redirect) {
932
933 this.redirect = redirect;
934
935 }
936
937
938
939
940
941
942
943
944
945
946
947 public void setRequiretools(boolean requireTools) {
948
949 this.requireTools = requireTools;
950
951 }
952
953
954
955
956
957
958
959
960
961 private boolean testIfCondition(String ifCondition) {
962
963 if (ifCondition == null || "".equals(ifCondition))
964 return true;
965 return project.getProperty(ifCondition) != null;
966
967 }
968
969
970
971
972
973
974
975
976
977 private boolean testUnlessCondition(String unlessCondition) {
978
979 if (unlessCondition == null || "".equals(unlessCondition))
980 return true;
981 return project.getProperty(unlessCondition) == null;
982
983 }
984
985 }