1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.start;
20
21 import java.io.BufferedReader;
22 import java.io.Closeable;
23 import java.io.File;
24 import java.io.FileFilter;
25 import java.io.FileInputStream;
26 import java.io.FileNotFoundException;
27 import java.io.FileOutputStream;
28 import java.io.FileReader;
29 import java.io.FilenameFilter;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.InputStreamReader;
33 import java.io.LineNumberReader;
34 import java.io.OutputStream;
35 import java.io.PrintStream;
36 import java.lang.reflect.InvocationTargetException;
37 import java.lang.reflect.Method;
38 import java.net.ConnectException;
39 import java.net.InetAddress;
40 import java.net.Socket;
41 import java.net.SocketTimeoutException;
42 import java.text.SimpleDateFormat;
43 import java.util.ArrayList;
44 import java.util.Arrays;
45 import java.util.Collections;
46 import java.util.Date;
47 import java.util.HashSet;
48 import java.util.List;
49 import java.util.Locale;
50 import java.util.Properties;
51 import java.util.Set;
52
53
54
55
56
57
58
59
60
61
62
63
64 public class Main
65 {
66 private static final String START_LOG_FILENAME = "start.log";
67 private static final SimpleDateFormat START_LOG_ROLLOVER_DATEFORMAT = new SimpleDateFormat("yyyy_MM_dd-HHmmSSSSS.'" + START_LOG_FILENAME + "'");
68
69 private static final int EXIT_USAGE = 1;
70 private static final int ERR_LOGGING = -1;
71 private static final int ERR_INVOKE_MAIN = -2;
72 private static final int ERR_NOT_STOPPED = -4;
73 private static final int ERR_UNKNOWN = -5;
74 private boolean _showUsage = false;
75 private boolean _dumpVersions = false;
76 private boolean _listConfig = false;
77 private boolean _listOptions = false;
78 private boolean _dryRun = false;
79 private boolean _exec = false;
80 private final Config _config = new Config();
81 private final Set<String> _sysProps = new HashSet<String>();
82 private final List<String> _jvmArgs = new ArrayList<String>();
83 private String _startConfig = null;
84
85 private String _jettyHome;
86
87 public static void main(String[] args)
88 {
89 try
90 {
91 Main main = new Main();
92 List<String> arguments = main.expandCommandLine(args);
93 List<String> xmls = main.processCommandLine(arguments);
94 if (xmls!=null)
95 main.start(xmls);
96 }
97 catch (Throwable e)
98 {
99 usageExit(e,ERR_UNKNOWN);
100 }
101 }
102
103 Main() throws IOException
104 {
105 _jettyHome = System.getProperty("jetty.home",".");
106 _jettyHome = new File(_jettyHome).getCanonicalPath();
107 }
108
109 public List<String> expandCommandLine(String[] args) throws Exception
110 {
111 List<String> arguments = new ArrayList<String>();
112
113
114 boolean ini = false;
115 for (String arg : args)
116 {
117 if (arg.startsWith("--ini=") || arg.equals("--ini"))
118 {
119 ini = true;
120 if (arg.length() > 6)
121 {
122 arguments.addAll(loadStartIni(new File(arg.substring(6))));
123 }
124 }
125 else if (arg.startsWith("--config="))
126 {
127 _startConfig = arg.substring(9);
128 }
129 else
130 {
131 arguments.add(arg);
132 }
133 }
134
135
136 if (!ini)
137 {
138 arguments.addAll(0,parseStartIniFiles());
139 }
140
141 return arguments;
142 }
143
144 List<String> parseStartIniFiles()
145 {
146 List<String> ini_args=new ArrayList<String>();
147 File start_ini = new File(_jettyHome,"start.ini");
148 if (start_ini.exists())
149 ini_args.addAll(loadStartIni(start_ini));
150
151 File start_d = new File(_jettyHome,"start.d");
152 if (start_d.isDirectory())
153 {
154 File[] inis = start_d.listFiles(new FilenameFilter()
155 {
156 public boolean accept(File dir, String name)
157 {
158 return name.toLowerCase(Locale.ENGLISH).endsWith(".ini");
159 }
160 });
161 Arrays.sort(inis);
162 for (File i : inis)
163 ini_args.addAll(loadStartIni(i));
164 }
165 return ini_args;
166 }
167
168 public List<String> processCommandLine(List<String> arguments) throws Exception
169 {
170
171 List<String> xmls = new ArrayList<String>();
172
173
174 int startup = 0;
175 for (String arg : arguments)
176 {
177 if ("--help".equals(arg) || "-?".equals(arg))
178 {
179 _showUsage = true;
180 continue;
181 }
182
183 if ("--stop".equals(arg))
184 {
185 int port = Integer.parseInt(Config.getProperty("STOP.PORT","-1"));
186 String key = Config.getProperty("STOP.KEY",null);
187 int timeout = Integer.parseInt(Config.getProperty("STOP.WAIT", "0"));
188 stop(port,key,timeout);
189 return null;
190 }
191
192 if ("--version".equals(arg) || "-v".equals(arg) || "--info".equals(arg))
193 {
194 _dumpVersions = true;
195 continue;
196 }
197
198 if ("--list-modes".equals(arg) || "--list-options".equals(arg))
199 {
200 _listOptions = true;
201 continue;
202 }
203
204 if ("--list-config".equals(arg))
205 {
206 _listConfig = true;
207 continue;
208 }
209
210 if ("--exec-print".equals(arg) || "--dry-run".equals(arg))
211 {
212 _dryRun = true;
213 continue;
214 }
215
216 if ("--exec".equals(arg))
217 {
218 _exec = true;
219 continue;
220 }
221
222
223 if ("--daemon".equals(arg))
224 {
225 File startDir = new File(System.getProperty("jetty.logs","logs"));
226 if (!startDir.exists() || !startDir.canWrite())
227 startDir = new File(".");
228
229 File startLog = new File(startDir, START_LOG_ROLLOVER_DATEFORMAT.format(new Date()));
230
231 if (!startLog.exists() && !startLog.createNewFile())
232 {
233
234 System.err.println("Unable to create: " + startLog.getAbsolutePath());
235
236 usageExit(ERR_LOGGING);
237 }
238
239 if (!startLog.canWrite())
240 {
241
242 System.err.println("Unable to write to: " + startLog.getAbsolutePath());
243
244 usageExit(ERR_LOGGING);
245 }
246 PrintStream logger = new PrintStream(new FileOutputStream(startLog,false));
247 System.setOut(logger);
248 System.setErr(logger);
249 System.out.println("Establishing "+ START_LOG_FILENAME + " on " + new Date());
250 continue;
251 }
252
253 if (arg.startsWith("--pre="))
254 {
255 xmls.add(startup++,arg.substring(6));
256 continue;
257 }
258
259 if (arg.startsWith("-D"))
260 {
261 String[] assign = arg.substring(2).split("=",2);
262 _sysProps.add(assign[0]);
263 switch (assign.length)
264 {
265 case 2:
266 System.setProperty(assign[0],assign[1]);
267 break;
268 case 1:
269 System.setProperty(assign[0],"");
270 break;
271 default:
272 break;
273 }
274 continue;
275 }
276
277 if (arg.startsWith("-"))
278 {
279 _jvmArgs.add(arg);
280 continue;
281 }
282
283
284 if (arg.indexOf('=') >= 0)
285 {
286 String[] assign = arg.split("=",2);
287
288 switch (assign.length)
289 {
290 case 2:
291 if ("OPTIONS".equals(assign[0]))
292 {
293 String opts[] = assign[1].split(",");
294 for (String opt : opts)
295 _config.addActiveOption(opt.trim());
296 }
297 else
298 {
299 this._config.setProperty(assign[0],assign[1]);
300 }
301 break;
302 case 1:
303 this._config.setProperty(assign[0],null);
304 break;
305 default:
306 break;
307 }
308
309 continue;
310 }
311
312
313 if (xmls.contains(arg))
314 {
315 System.out.println("WARN: Argument '" + arg + "' specified multiple times. Check start.ini?");
316 System.out.println("Use \"java -jar start.jar --help\" for more information.");
317 }
318 xmls.add(arg);
319 }
320
321 return xmls;
322 }
323
324 private void usage()
325 {
326 String usageResource = "org/eclipse/jetty/start/usage.txt";
327 InputStream usageStream = getClass().getClassLoader().getResourceAsStream(usageResource);
328
329 if (usageStream == null)
330 {
331 System.err.println("ERROR: detailed usage resource unavailable");
332 usageExit(EXIT_USAGE);
333 }
334
335 BufferedReader buf = null;
336 try
337 {
338 buf = new BufferedReader(new InputStreamReader(usageStream));
339 String line;
340
341 while ((line = buf.readLine()) != null)
342 {
343 if (line.endsWith("@") && line.indexOf('@') != line.lastIndexOf('@'))
344 {
345 String indent = line.substring(0,line.indexOf("@"));
346 String info = line.substring(line.indexOf('@'),line.lastIndexOf('@'));
347
348 if (info.equals("@OPTIONS"))
349 {
350 List<String> sortedOptions = new ArrayList<String>();
351 sortedOptions.addAll(_config.getSectionIds());
352 Collections.sort(sortedOptions);
353
354 for (String option : sortedOptions)
355 {
356 if ("*".equals(option) || option.trim().length() == 0)
357 continue;
358 System.out.print(indent);
359 System.out.println(option);
360 }
361 }
362 else if (info.equals("@CONFIGS"))
363 {
364 File etc = new File(System.getProperty("jetty.home","."),"etc");
365 if (!etc.exists() || !etc.isDirectory())
366 {
367 System.out.print(indent);
368 System.out.println("Unable to find/list " + etc);
369 continue;
370 }
371
372 File configs[] = etc.listFiles(new FileFilter()
373 {
374 public boolean accept(File path)
375 {
376 if (!path.isFile())
377 {
378 return false;
379 }
380
381 String name = path.getName().toLowerCase(Locale.ENGLISH);
382 return (name.startsWith("jetty") && name.endsWith(".xml"));
383 }
384 });
385
386 List<File> configFiles = new ArrayList<File>();
387 configFiles.addAll(Arrays.asList(configs));
388 Collections.sort(configFiles);
389
390 for (File configFile : configFiles)
391 {
392 System.out.print(indent);
393 System.out.print("etc/");
394 System.out.println(configFile.getName());
395 }
396 }
397 else if (info.equals("@STARTINI"))
398 {
399 List<String> ini = loadStartIni(new File(_jettyHome,"start.ini"));
400 if (ini != null && ini.size() > 0)
401 {
402 for (String a : ini)
403 {
404 System.out.print(indent);
405 System.out.println(a);
406 }
407 }
408 else
409 {
410 System.out.print(indent);
411 System.out.println("none");
412 }
413 }
414 }
415 else
416 {
417 System.out.println(line);
418 }
419 }
420 }
421 catch (IOException e)
422 {
423 usageExit(e,EXIT_USAGE);
424 }
425 finally
426 {
427 close(buf);
428 }
429 System.exit(EXIT_USAGE);
430 }
431
432 public void invokeMain(ClassLoader classloader, String classname, List<String> args) throws IllegalAccessException, InvocationTargetException,
433 NoSuchMethodException, ClassNotFoundException
434 {
435 Class<?> invoked_class = null;
436
437 try
438 {
439 invoked_class = classloader.loadClass(classname);
440 }
441 catch (ClassNotFoundException e)
442 {
443 e.printStackTrace();
444 }
445
446 if (Config.isDebug() || invoked_class == null)
447 {
448 if (invoked_class == null)
449 {
450 System.err.println("ClassNotFound: " + classname);
451 }
452 else
453 {
454 System.err.println(classname + " " + invoked_class.getPackage().getImplementationVersion());
455 }
456
457 if (invoked_class == null)
458 {
459 usageExit(ERR_INVOKE_MAIN);
460 return;
461 }
462 }
463
464 String argArray[] = args.toArray(new String[0]);
465
466 Class<?>[] method_param_types = new Class[]
467 { argArray.getClass() };
468
469 Method main = invoked_class.getDeclaredMethod("main",method_param_types);
470 Object[] method_params = new Object[]
471 { argArray };
472 main.invoke(null,method_params);
473 }
474
475
476 public static void close(Closeable c)
477 {
478 if (c == null)
479 {
480 return;
481 }
482 try
483 {
484 c.close();
485 }
486 catch (IOException e)
487 {
488 e.printStackTrace(System.err);
489 }
490 }
491
492
493 public void start(List<String> xmls) throws IOException, InterruptedException
494 {
495
496 int port = Integer.parseInt(Config.getProperty("STOP.PORT","-1"));
497 String key = Config.getProperty("STOP.KEY",null);
498 Monitor monitor = new Monitor(port,key);
499
500
501 List<String> configuredXmls = loadConfig(xmls);
502
503
504 if (configuredXmls.isEmpty())
505 {
506 throw new FileNotFoundException("No XML configuration files specified in start.config or command line.");
507 }
508
509
510 configuredXmls = resolveXmlConfigs(configuredXmls);
511
512
513 Classpath classpath = _config.getActiveClasspath();
514
515 System.setProperty("java.class.path",classpath.toString());
516 ClassLoader cl = classpath.getClassLoader();
517 if (Config.isDebug())
518 {
519 System.err.println("java.class.path=" + System.getProperty("java.class.path"));
520 System.err.println("jetty.home=" + System.getProperty("jetty.home"));
521 System.err.println("java.home=" + System.getProperty("java.home"));
522 System.err.println("java.io.tmpdir=" + System.getProperty("java.io.tmpdir"));
523 System.err.println("java.class.path=" + classpath);
524 System.err.println("classloader=" + cl);
525 System.err.println("classloader.parent=" + cl.getParent());
526 System.err.println("properties=" + Config.getProperties());
527 }
528
529
530 if (_showUsage)
531 {
532 usage();
533 return;
534 }
535
536
537 if (_dumpVersions)
538 {
539 showClasspathWithVersions(classpath);
540 return;
541 }
542
543
544 if (_listOptions)
545 {
546 showAllOptionsWithVersions();
547 return;
548 }
549
550 if (_listConfig)
551 {
552 listConfig();
553 return;
554 }
555
556
557 if (_dryRun)
558 {
559 CommandLineBuilder cmd = buildCommandLine(classpath,configuredXmls);
560 System.out.println(cmd.toString());
561 return;
562 }
563
564
565 if (_exec)
566 {
567 CommandLineBuilder cmd = buildCommandLine(classpath,configuredXmls);
568
569 ProcessBuilder pbuilder = new ProcessBuilder(cmd.getArgs());
570 final Process process = pbuilder.start();
571 Runtime.getRuntime().addShutdownHook(new Thread()
572 {
573 @Override
574 public void run()
575 {
576 Config.debug("Destroying " + process);
577 process.destroy();
578 }
579 });
580
581 copyInThread(process.getErrorStream(),System.err);
582 copyInThread(process.getInputStream(),System.out);
583 copyInThread(System.in,process.getOutputStream());
584 monitor.setProcess(process);
585 process.waitFor();
586
587 return;
588 }
589
590 if (_jvmArgs.size() > 0 || _sysProps.size() > 0)
591 {
592 System.err.println("WARNING: System properties and/or JVM args set. Consider using --dry-run or --exec");
593 }
594
595
596 Thread.currentThread().setContextClassLoader(cl);
597
598
599 try
600 {
601
602 String classname = _config.getMainClassname();
603
604
605 String mainClass = System.getProperty("jetty.server");
606 if (mainClass != null)
607 {
608 classname = mainClass;
609 }
610
611
612 mainClass = System.getProperty("main.class");
613 if (mainClass != null)
614 {
615 classname = mainClass;
616 }
617
618 Config.debug("main.class=" + classname);
619
620 invokeMain(cl,classname,configuredXmls);
621 }
622 catch (Exception e)
623 {
624 usageExit(e,ERR_INVOKE_MAIN);
625 }
626 }
627
628 private void copyInThread(final InputStream in, final OutputStream out)
629 {
630 new Thread(new Runnable()
631 {
632 public void run()
633 {
634 try
635 {
636 byte[] buf = new byte[1024];
637 int len = in.read(buf);
638 while (len > 0)
639 {
640 out.write(buf,0,len);
641 len = in.read(buf);
642 }
643 }
644 catch (IOException e)
645 {
646
647 }
648 }
649
650 }).start();
651 }
652
653 private String resolveXmlConfig(String xmlFilename) throws FileNotFoundException
654 {
655 if (!xmlFilename.toLowerCase(Locale.ENGLISH).endsWith(".xml"))
656 {
657
658 return xmlFilename;
659 }
660
661 File xml = new File(xmlFilename);
662 if (xml.exists() && xml.isFile())
663 {
664 return xml.getAbsolutePath();
665 }
666
667 xml = new File(_jettyHome,fixPath(xmlFilename));
668 if (xml.exists() && xml.isFile())
669 {
670 return xml.getAbsolutePath();
671 }
672
673 xml = new File(_jettyHome,fixPath("etc/" + xmlFilename));
674 if (xml.exists() && xml.isFile())
675 {
676 return xml.getAbsolutePath();
677 }
678
679 throw new FileNotFoundException("Unable to find XML Config: " + xmlFilename);
680 }
681
682 CommandLineBuilder buildCommandLine(Classpath classpath, List<String> xmls) throws IOException
683 {
684 CommandLineBuilder cmd = new CommandLineBuilder(findJavaBin());
685
686 for (String x : _jvmArgs)
687 {
688 cmd.addArg(x);
689 }
690 cmd.addRawArg("-Djetty.home=" + _jettyHome);
691 for (String p : _sysProps)
692 {
693 String v = System.getProperty(p);
694 cmd.addEqualsArg("-D" + p,v);
695 }
696 cmd.addArg("-cp");
697 cmd.addRawArg(classpath.toString());
698 cmd.addRawArg(_config.getMainClassname());
699
700
701 Properties properties = Config.getProperties();
702 if (properties.size() > 0)
703 {
704 File prop_file = File.createTempFile("start",".properties");
705 if (!_dryRun)
706 prop_file.deleteOnExit();
707 properties.store(new FileOutputStream(prop_file),"start.jar properties");
708 cmd.addArg(prop_file.getAbsolutePath());
709 }
710
711 for (String xml : xmls)
712 {
713 cmd.addRawArg(xml);
714 }
715 return cmd;
716 }
717
718 private String findJavaBin()
719 {
720 File javaHome = new File(System.getProperty("java.home"));
721 if (!javaHome.exists())
722 {
723 return null;
724 }
725
726 File javabin = findExecutable(javaHome,"bin/java");
727 if (javabin != null)
728 {
729 return javabin.getAbsolutePath();
730 }
731
732 javabin = findExecutable(javaHome,"bin/java.exe");
733 if (javabin != null)
734 {
735 return javabin.getAbsolutePath();
736 }
737
738 return "java";
739 }
740
741 private File findExecutable(File root, String path)
742 {
743 String npath = path.replace('/',File.separatorChar);
744 File exe = new File(root,npath);
745 if (!exe.exists())
746 {
747 return null;
748 }
749 return exe;
750 }
751
752 private void showAllOptionsWithVersions()
753 {
754 Set<String> sectionIds = _config.getSectionIds();
755
756 StringBuffer msg = new StringBuffer();
757 msg.append("There ");
758 if (sectionIds.size() > 1)
759 {
760 msg.append("are ");
761 }
762 else
763 {
764 msg.append("is ");
765 }
766 msg.append(String.valueOf(sectionIds.size()));
767 msg.append(" OPTION");
768 if (sectionIds.size() > 1)
769 {
770 msg.append("s");
771 }
772 msg.append(" available to use.");
773 System.out.println(msg);
774 System.out.println("Each option is listed along with associated available classpath entries, in the order that they would appear from that mode.");
775 System.out.println("Note: If using multiple options (eg: 'Server,servlet,webapp,jms,jmx') "
776 + "then overlapping entries will not be repeated in the eventual classpath.");
777 System.out.println();
778 System.out.printf("${jetty.home} = %s%n",_jettyHome);
779 System.out.println();
780
781 for (String sectionId : sectionIds)
782 {
783 if (Config.DEFAULT_SECTION.equals(sectionId))
784 {
785 System.out.println("GLOBAL option (Prepended Entries)");
786 }
787 else if ("*".equals(sectionId))
788 {
789 System.out.println("GLOBAL option (Appended Entries) (*)");
790 }
791 else
792 {
793 System.out.printf("Option [%s]",sectionId);
794 if (Character.isUpperCase(sectionId.charAt(0)))
795 {
796 System.out.print(" (Aggregate)");
797 }
798 System.out.println();
799 }
800 System.out.println("-------------------------------------------------------------");
801
802 Classpath sectionCP = _config.getSectionClasspath(sectionId);
803
804 if (sectionCP.isEmpty())
805 {
806 System.out.println("Empty option, no classpath entries active.");
807 System.out.println();
808 continue;
809 }
810
811 int i = 0;
812 for (File element : sectionCP.getElements())
813 {
814 String elementPath = element.getAbsolutePath();
815 if (elementPath.startsWith(_jettyHome))
816 {
817 elementPath = "${jetty.home}" + elementPath.substring(_jettyHome.length());
818 }
819 System.out.printf("%2d: %20s | %s\n",i++,getVersion(element),elementPath);
820 }
821
822 System.out.println();
823 }
824 }
825
826 private void showClasspathWithVersions(Classpath classpath)
827 {
828
829
830
831 System.out.println("Active Options: " + _config.getActiveOptions());
832
833 if (classpath.count() == 0)
834 {
835 System.out.println("No version information available show.");
836 return;
837 }
838
839 System.out.println("Version Information on " + classpath.count() + " entr" + ((classpath.count() > 1)?"ies":"y") + " in the classpath.");
840 System.out.println("Note: order presented here is how they would appear on the classpath.");
841 System.out.println(" changes to the OPTIONS=[option,option,...] command line option will be reflected here.");
842
843 int i = 0;
844 for (File element : classpath.getElements())
845 {
846 String elementPath = element.getAbsolutePath();
847 if (elementPath.startsWith(_jettyHome))
848 {
849 elementPath = "${jetty.home}" + elementPath.substring(_jettyHome.length());
850 }
851 System.out.printf("%2d: %20s | %s\n",i++,getVersion(element),elementPath);
852 }
853 }
854
855 private String fixPath(String path)
856 {
857 return path.replace('/',File.separatorChar);
858 }
859
860 private String getVersion(File element)
861 {
862 if (element.isDirectory())
863 {
864 return "(dir)";
865 }
866
867 if (element.isFile())
868 {
869 String name = element.getName().toLowerCase(Locale.ENGLISH);
870 if (name.endsWith(".jar"))
871 {
872 return JarVersion.getVersion(element);
873 }
874
875 if (name.endsWith(".zip"))
876 {
877 return getZipVersion(element);
878 }
879 }
880
881 return "";
882 }
883
884 private String getZipVersion(File element)
885 {
886
887 return "";
888 }
889
890 private List<String> resolveXmlConfigs(List<String> xmls) throws FileNotFoundException
891 {
892 List<String> ret = new ArrayList<String>();
893 for (String xml : xmls)
894 {
895 ret.add(resolveXmlConfig(xml));
896 }
897
898 return ret;
899 }
900
901 private void listConfig()
902 {
903 InputStream cfgstream = null;
904 try
905 {
906 cfgstream = getConfigStream();
907 byte[] buf = new byte[4096];
908
909 int len = 0;
910
911 while (len >= 0)
912 {
913 len = cfgstream.read(buf);
914 if (len > 0)
915 System.out.write(buf,0,len);
916 }
917 }
918 catch (Exception e)
919 {
920 usageExit(e,ERR_UNKNOWN);
921 }
922 finally
923 {
924 close(cfgstream);
925 }
926 }
927
928
929
930
931
932
933
934
935
936
937
938 private List<String> loadConfig(List<String> xmls)
939 {
940 InputStream cfgstream = null;
941 try
942 {
943
944 _config.setArgCount(xmls.size());
945
946 cfgstream = getConfigStream();
947
948
949 _config.parse(cfgstream);
950
951 _jettyHome = Config.getProperty("jetty.home",_jettyHome);
952 if (_jettyHome != null)
953 {
954 _jettyHome = new File(_jettyHome).getCanonicalPath();
955 System.setProperty("jetty.home",_jettyHome);
956 }
957
958
959 List<String> ret = new ArrayList<String>();
960 ret.addAll(xmls);
961 for (String xmlconfig : _config.getXmlConfigs())
962 {
963
964 if (!ret.contains(xmlconfig))
965 {
966 ret.add(xmlconfig);
967 }
968 }
969
970 return ret;
971 }
972 catch (Exception e)
973 {
974 usageExit(e,ERR_UNKNOWN);
975 return null;
976 }
977 finally
978 {
979 close(cfgstream);
980 }
981 }
982
983 private InputStream getConfigStream() throws FileNotFoundException
984 {
985 String config = _startConfig;
986 if (config == null || config.length() == 0)
987 {
988 config = System.getProperty("START","org/eclipse/jetty/start/start.config");
989 }
990
991 Config.debug("config=" + config);
992
993
994 InputStream cfgstream = getClass().getClassLoader().getResourceAsStream(config);
995
996
997 if (cfgstream == null)
998 {
999 cfgstream = new FileInputStream(config);
1000 }
1001
1002 return cfgstream;
1003 }
1004
1005
1006
1007
1008 public void stop(int port, String key)
1009 {
1010 stop (port,key, 0);
1011 }
1012
1013
1014 public void stop (int port, String key, int timeout)
1015 {
1016 int _port = port;
1017 String _key = key;
1018
1019 try
1020 {
1021 if (_port <= 0)
1022 {
1023 System.err.println("STOP.PORT system property must be specified");
1024 }
1025 if (_key == null)
1026 {
1027 _key = "";
1028 System.err.println("STOP.KEY system property must be specified");
1029 System.err.println("Using empty key");
1030 }
1031
1032 Socket s = new Socket(InetAddress.getByName("127.0.0.1"),_port);
1033 if (timeout > 0)
1034 s.setSoTimeout(timeout*1000);
1035 try
1036 {
1037 OutputStream out = s.getOutputStream();
1038 out.write((_key + "\r\nstop\r\n").getBytes());
1039 out.flush();
1040
1041 if (timeout > 0)
1042 {
1043 System.err.println("Waiting"+(timeout > 0 ? (" "+timeout+"sec") : "")+" for jetty to stop");
1044 LineNumberReader lin = new LineNumberReader(new InputStreamReader(s.getInputStream()));
1045 String response=lin.readLine();
1046 if ("Stopped".equals(response))
1047 System.err.println("Stopped");
1048 }
1049 }
1050 finally
1051 {
1052 s.close();
1053 }
1054 }
1055 catch (SocketTimeoutException e)
1056 {
1057 System.err.println("Timed out waiting for stop confirmation");
1058 System.exit(ERR_UNKNOWN);
1059 }
1060 catch (ConnectException e)
1061 {
1062 usageExit(e,ERR_NOT_STOPPED);
1063 }
1064 catch (Exception e)
1065 {
1066 usageExit(e,ERR_UNKNOWN);
1067 }
1068 }
1069
1070 static void usageExit(Throwable t, int exit)
1071 {
1072 t.printStackTrace(System.err);
1073 System.err.println();
1074 System.err.println("Usage: java -jar start.jar [options] [properties] [configs]");
1075 System.err.println(" java -jar start.jar --help # for more information");
1076 System.exit(exit);
1077 }
1078
1079 static void usageExit(int exit)
1080 {
1081 System.err.println();
1082 System.err.println("Usage: java -jar start.jar [options] [properties] [configs]");
1083 System.err.println(" java -jar start.jar --help # for more information");
1084 System.exit(exit);
1085 }
1086
1087
1088
1089
1090 static List<String> loadStartIni(File ini)
1091 {
1092 if (!ini.exists())
1093 {
1094 System.err.println("Warning - can't find ini file: " + ini);
1095
1096 return Collections.emptyList();
1097 }
1098
1099 List<String> args = new ArrayList<String>();
1100
1101 FileReader reader = null;
1102 BufferedReader buf = null;
1103 try
1104 {
1105 reader = new FileReader(ini);
1106 buf = new BufferedReader(reader);
1107
1108 String arg;
1109 while ((arg = buf.readLine()) != null)
1110 {
1111 arg = arg.trim();
1112 if (arg.length() == 0 || arg.startsWith("#"))
1113 {
1114 continue;
1115 }
1116 args.add(arg);
1117 }
1118 }
1119 catch (IOException e)
1120 {
1121 usageExit(e,ERR_UNKNOWN);
1122 }
1123 finally
1124 {
1125 Main.close(buf);
1126 Main.close(reader);
1127 }
1128
1129 return args;
1130 }
1131
1132 void addJvmArgs(List<String> jvmArgs)
1133 {
1134 _jvmArgs.addAll(jvmArgs);
1135 }
1136 }