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