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.File;
17 import java.io.FileInputStream;
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.io.InputStreamReader;
21 import java.io.OutputStream;
22 import java.lang.reflect.InvocationTargetException;
23 import java.lang.reflect.Method;
24 import java.net.ConnectException;
25 import java.net.InetAddress;
26 import java.net.Socket;
27 import java.security.Policy;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.Collections;
31 import java.util.HashSet;
32 import java.util.Hashtable;
33 import java.util.List;
34 import java.util.Set;
35 import java.util.StringTokenizer;
36
37
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102 public class Main
103 {
104 private static final String _version = (Main.class.getPackage()!=null && Main.class.getPackage().getImplementationVersion()!=null)
105 ?Main.class.getPackage().getImplementationVersion()
106 :"Unknown";
107
108 static boolean _debug=System.getProperty("DEBUG",null)!=null;
109 private String _classname=null;
110 private Classpath _classpath=new Classpath();
111 private String _config=System.getProperty("START","org/eclipse/jetty/start/start.config");
112 private ArrayList _xml=new ArrayList();
113 private boolean _showVersions=false;
114 private Set _options = new HashSet();
115
116 public static void main(String[] args)
117 {
118 try
119 {
120 if (args.length>0&&args[0].equalsIgnoreCase("--help"))
121 {
122 usage();
123 }
124 else if (args.length>0&&args[0].equalsIgnoreCase("--stop"))
125 {
126 new Main().stop();
127 }
128 else if (args.length>0&&(args[0].equalsIgnoreCase("--version")||args[0].equalsIgnoreCase("--info")))
129 {
130 String[] nargs=new String[args.length-1];
131 System.arraycopy(args,1,nargs,0,nargs.length);
132 Main main=new Main();
133 main._showVersions=true;
134 main.start(nargs);
135 }
136 else
137 {
138 new Main().start(args);
139 }
140 }
141 catch (Exception e)
142 {
143 e.printStackTrace();
144 usage();
145 }
146 }
147
148 private static void usage()
149 {
150 System.err.println("Usage: java [-DDEBUG] [-DSTART=start.config] [-DOPTIONS=opts] [-Dmain.class=org.MyMain] -jar start.jar [--help|--stop|--version|--info] [config ...]");
151 System.exit(1);
152 }
153
154 static File getDirectory(String name)
155 {
156 try
157 {
158 if (name!=null)
159 {
160 File dir=new File(name).getCanonicalFile();
161 if (dir.isDirectory())
162 {
163 return dir;
164 }
165 }
166 }
167 catch (IOException e)
168 {
169 }
170 return null;
171 }
172
173 boolean isAvailable(String classname)
174 {
175 try
176 {
177 Class.forName(classname);
178 return true;
179 }
180 catch (NoClassDefFoundError e)
181 {
182 if (_debug)
183 System.err.println(e);
184 }
185 catch (ClassNotFoundException e)
186 {
187 if (_debug)
188 System.err.println(e);
189 }
190 ClassLoader loader=_classpath.getClassLoader();
191 try
192 {
193 loader.loadClass(classname);
194 return true;
195 }
196 catch (NoClassDefFoundError e)
197 {
198 if (_debug)
199 System.err.println(e);
200 }
201 catch (ClassNotFoundException e)
202 {
203 if (_debug)
204 System.err.println(e);
205 }
206 return false;
207 }
208
209 public void invokeMain(ClassLoader classloader, String classname, String[] args) throws IllegalAccessException, InvocationTargetException,
210 NoSuchMethodException, ClassNotFoundException
211 {
212 Class invoked_class=null;
213
214 try
215 {
216 invoked_class=classloader.loadClass(classname);
217 }
218 catch(ClassNotFoundException e)
219 {
220
221 }
222
223 if (_debug || _showVersions || invoked_class==null)
224 {
225 if (invoked_class==null)
226 System.err.println("ClassNotFound: "+classname);
227 else
228 System.err.println(classname+" "+invoked_class.getPackage().getImplementationVersion());
229 File[] elements = _classpath.getElements();
230 for (int i=0;i<elements.length;i++)
231 System.err.println(" "+elements[i].getAbsolutePath());
232 if (_showVersions || invoked_class==null)
233 {
234 List opts = new ArrayList(_options);
235 Collections.sort(opts);
236 System.err.println("OPTIONS: "+opts);
237 usage();
238 }
239 }
240
241 Class[] method_param_types=new Class[1];
242 method_param_types[0]=args.getClass();
243 Method main=null;
244 main=invoked_class.getDeclaredMethod("main",method_param_types);
245 Object[] method_params=new Object[1];
246 method_params[0]=args;
247
248 main.invoke(null,method_params);
249 }
250
251
252 String expand(String s)
253 {
254 int i1=0;
255 int i2=0;
256 while (s!=null)
257 {
258 i1=s.indexOf("$(",i2);
259 if (i1<0)
260 break;
261 i2=s.indexOf(")",i1+2);
262 if (i2<0)
263 break;
264 String name=s.substring(i1+2,i2);
265 String property;
266 if ("version".equalsIgnoreCase(name))
267 property=_version;
268 else
269 property=System.getProperty(s.substring(i1+2,i2),"");
270 s=s.substring(0,i1)+property+s.substring(i2+1);
271 }
272 return s;
273 }
274
275
276 void configure(InputStream config, int nargs) throws Exception
277 {
278 BufferedReader cfg=new BufferedReader(new InputStreamReader(config,"ISO-8859-1"));
279 Version java_version=new Version(System.getProperty("java.version"));
280 Version ver=new Version();
281
282 Hashtable done=new Hashtable();
283
284 String classpath=System.getProperty("CLASSPATH");
285 if (classpath!=null)
286 {
287 StringTokenizer tok=new StringTokenizer(classpath,File.pathSeparator);
288 while (tok.hasMoreTokens())
289 _classpath.addComponent(tok.nextToken());
290 }
291
292 List section=null;
293 List options=null;
294 String o=System.getProperty("OPTIONS");
295 if (o==null)
296 o="default";
297 options=Arrays.asList((o.toString()+",*").split("[ ,]"));
298 ArrayList unsatisfiedOptions = new ArrayList(options);
299
300
301 String line=null;
302 while (true)
303 {
304 line=cfg.readLine();
305 if (line==null)
306 break;
307 String trim=line.trim();
308 if (trim.length()==0||trim.startsWith("#"))
309 continue;
310
311
312 if (trim.startsWith("[") && trim.endsWith("]"))
313 {
314 section = Arrays.asList(trim.substring(1,trim.length()-1).split("[ ,]"));
315 _options.addAll(section);
316 }
317
318 if (section!=null && Collections.disjoint(section,options))
319 continue;
320 if (section!=null)
321 unsatisfiedOptions.removeAll(section);
322 try
323 {
324 StringTokenizer st=new StringTokenizer(line);
325 String subject=st.nextToken();
326 boolean expression=true;
327 boolean not=false;
328 String condition=null;
329
330 while (st.hasMoreTokens())
331 {
332 condition=st.nextToken();
333 if (condition.equalsIgnoreCase("!"))
334 {
335 not=true;
336 continue;
337 }
338 if (condition.equalsIgnoreCase("OR"))
339 {
340 if (expression)
341 break;
342 expression=true;
343 continue;
344 }
345 if (condition.equalsIgnoreCase("AND"))
346 {
347 if (!expression)
348 break;
349 continue;
350 }
351 boolean eval=true;
352 if (condition.equals("true")||condition.equals("always"))
353 {
354 eval=true;
355 }
356 else if (condition.equals("false")||condition.equals("never"))
357 {
358 eval=false;
359 }
360 else if (condition.equals("available"))
361 {
362 String class_to_check=st.nextToken();
363 eval=isAvailable(class_to_check);
364 }
365 else if (condition.equals("exists"))
366 {
367 try
368 {
369 eval=false;
370 File file=new File(expand(st.nextToken()));
371 eval=file.exists();
372 }
373 catch (Exception e)
374 {
375 if (_debug)
376 e.printStackTrace();
377 }
378 }
379 else if (condition.equals("property"))
380 {
381 String property=System.getProperty(st.nextToken());
382 eval=property!=null&&property.length()>0;
383 }
384 else if (condition.equals("java"))
385 {
386 String operator=st.nextToken();
387 String version=st.nextToken();
388 ver.parse(version);
389 eval=(operator.equals("<")&&java_version.compare(ver)<0)||(operator.equals(">")&&java_version.compare(ver)>0)
390 ||(operator.equals("<=")&&java_version.compare(ver)<=0)||(operator.equals("=<")&&java_version.compare(ver)<=0)
391 ||(operator.equals("=>")&&java_version.compare(ver)>=0)||(operator.equals(">=")&&java_version.compare(ver)>=0)
392 ||(operator.equals("==")&&java_version.compare(ver)==0)||(operator.equals("!=")&&java_version.compare(ver)!=0);
393 }
394 else if (condition.equals("nargs"))
395 {
396 String operator=st.nextToken();
397 int number=Integer.parseInt(st.nextToken());
398 eval=(operator.equals("<")&&nargs<number)||(operator.equals(">")&&nargs>number)||(operator.equals("<=")&&nargs<=number)
399 ||(operator.equals("=<")&&nargs<=number)||(operator.equals("=>")&&nargs>=number)||(operator.equals(">=")&&nargs>=number)
400 ||(operator.equals("==")&&nargs==number)||(operator.equals("!=")&&nargs!=number);
401 }
402 else
403 {
404 System.err.println("ERROR: Unknown condition: "+condition);
405 eval=false;
406 }
407 expression&=not?!eval:eval;
408 not=false;
409 }
410 String file=expand(subject).replace('/',File.separatorChar);
411 if (_debug)
412 System.err.println((expression?"T ":"F ")+line);
413 if (!expression)
414 {
415 done.put(file,file);
416 continue;
417 }
418
419 if (subject.indexOf("=")>0)
420 {
421 int i=file.indexOf("=");
422 String property=file.substring(0,i);
423 String value=file.substring(i+1);
424 if (_debug)
425 System.err.println(" "+property+"="+value);
426 System.setProperty(property,value);
427 }
428 else if (subject.endsWith("/*"))
429 {
430
431
432 File dir=new File(file.substring(0,file.length()-1));
433 addJars(dir,done,false);
434 }
435 else if (subject.endsWith("/**"))
436 {
437
438
439 File dir=new File(file.substring(0,file.length()-2));
440 addJars(dir,done,true);
441 }
442 else if (subject.endsWith("/"))
443 {
444
445 File cd=new File(file);
446 String d=cd.getCanonicalPath();
447 if (!done.containsKey(d))
448 {
449 done.put(d,d);
450 boolean added=_classpath.addComponent(d);
451 if (_debug)
452 System.err.println((added?" CLASSPATH+=":" !")+d);
453 }
454 }
455 else if (subject.toLowerCase().endsWith(".xml"))
456 {
457
458 File f=new File(file);
459 if (f.exists())
460 _xml.add(f.getCanonicalPath());
461 if (_debug)
462 System.err.println(" ARGS+="+f);
463 }
464 else if (subject.toLowerCase().endsWith(".class"))
465 {
466
467 String cn=expand(subject.substring(0,subject.length()-6));
468 if (cn!=null&&cn.length()>0)
469 {
470 if (_debug)
471 System.err.println(" CLASS="+cn);
472 _classname=cn;
473 }
474 }
475 else if (subject.toLowerCase().endsWith(".path"))
476 {
477
478 String cn=expand(subject.substring(0,subject.length()-5));
479 if (cn!=null&&cn.length()>0)
480 {
481 if (_debug)
482 System.err.println(" PATH="+cn);
483 _classpath.addClasspath(cn);
484 }
485 }
486 else
487 {
488
489 File f=new File(file);
490 if(f.exists())
491 {
492 String d=f.getCanonicalPath();
493 if (!done.containsKey(d))
494 {
495 done.put(d,d);
496 boolean added=_classpath.addComponent(d);
497 if (!added)
498 {
499 added=_classpath.addClasspath(expand(subject));
500 if (_debug)
501 System.err.println((added?" CLASSPATH+=":" !")+d);
502 }
503 else if (_debug)
504 System.err.println((added?" CLASSPATH+=":" !")+d);
505 }
506 }
507 }
508 }
509 catch (Exception e)
510 {
511 System.err.println("on line: '"+line+"'");
512 e.printStackTrace();
513 }
514 }
515
516 if (unsatisfiedOptions!=null && unsatisfiedOptions.size()>0)
517 {
518 String home = System.getProperty("jetty.home");
519 String lib = System.getProperty("jetty.lib");
520 File libDir = null;
521 if (lib!=null)
522 {
523 libDir = new File (lib);
524 }
525 else if (home != null)
526 {
527 libDir = new File (home, "lib");
528 }
529
530 for (int i=0; i< unsatisfiedOptions.size(); i++)
531 {
532 if (libDir != null)
533 {
534 File dir = new File (libDir, (String)unsatisfiedOptions.get(i));
535 if (dir.exists())
536 addJars(dir,done,true);
537 else
538 System.err.println("Unsatisfied option:"+unsatisfiedOptions.get(i));
539 }
540 else
541 System.err.println("Unsatisfied option:"+unsatisfiedOptions.get(i));
542 }
543 }
544 }
545
546
547 public void start(String[] args)
548 {
549 ArrayList al=new ArrayList();
550 for (int i=0; i<args.length; i++)
551 {
552 if (args[i]==null)
553 continue;
554 else
555 al.add(args[i]);
556 }
557 args=(String[])al.toArray(new String[al.size()]);
558
559 InputStream cpcfg=null;
560 try
561 {
562 Monitor.monitor();
563
564 cpcfg=getClass().getClassLoader().getResourceAsStream(_config);
565 if (_debug)
566 System.err.println("config="+_config);
567 if (cpcfg==null)
568 cpcfg=new FileInputStream(_config);
569 configure(cpcfg,args.length);
570 String jetty_home=System.getProperty("jetty.home");
571 if (jetty_home!=null)
572 {
573 File file=new File(jetty_home);
574 String canonical=file.getCanonicalPath();
575 System.setProperty("jetty.home",canonical);
576 }
577 }
578 catch (Exception e)
579 {
580 e.printStackTrace();
581 System.exit(1);
582 }
583 finally
584 {
585 try
586 {
587 cpcfg.close();
588 }
589 catch (Exception e)
590 {
591 e.printStackTrace();
592 }
593 }
594
595 System.setProperty("java.class.path",_classpath.toString());
596 ClassLoader cl=_classpath.getClassLoader();
597 if (_debug)
598 {
599 System.err.println("java.class.path="+System.getProperty("java.class.path"));
600 System.err.println("jetty.home="+System.getProperty("jetty.home"));
601 System.err.println("java.io.tmpdir="+System.getProperty("java.io.tmpdir"));
602 System.err.println("java.class.path="+_classpath);
603 System.err.println("classloader="+cl);
604 System.err.println("classloader.parent="+cl.getParent());
605 }
606
607 Thread.currentThread().setContextClassLoader(cl);
608
609 try
610 {
611 Policy policy=Policy.getPolicy();
612 if (policy!=null)
613 policy.refresh();
614 }
615 catch (Exception e)
616 {
617 e.printStackTrace();
618 }
619 try
620 {
621 for (int i=0; i<args.length; i++)
622 {
623 if (args[i]==null)
624 continue;
625 _xml.add(args[i]);
626 }
627 args=(String[])_xml.toArray(args);
628
629 String mainClass=System.getProperty("jetty.server");
630 if (mainClass!=null)
631 _classname=mainClass;
632 mainClass=System.getProperty("main.class");
633 if (mainClass!=null)
634 _classname=mainClass;
635 if (_debug)
636 System.err.println("main.class="+_classname);
637 invokeMain(cl,_classname,args);
638 }
639 catch (Exception e)
640 {
641 e.printStackTrace();
642 }
643 }
644
645
646
647
648 public void stop()
649 {
650 int _port=Integer.getInteger("STOP.PORT",-1).intValue();
651 String _key=System.getProperty("STOP.KEY",null);
652
653 try
654 {
655 if (_port<=0)
656 System.err.println("STOP.PORT system property must be specified");
657 if (_key==null)
658 {
659 _key="";
660 System.err.println("STOP.KEY system property must be specified");
661 System.err.println("Using empty key");
662 }
663
664 Socket s=new Socket(InetAddress.getByName("127.0.0.1"),_port);
665 OutputStream out=s.getOutputStream();
666 out.write((_key+"\r\nstop\r\n").getBytes());
667 out.flush();
668 s.close();
669 }
670 catch (ConnectException e)
671 {
672 System.err.println("ERROR: Not running!");
673 }
674 catch (Exception e)
675 {
676 e.printStackTrace();
677 }
678 }
679
680 private void addJars(File dir, Hashtable table, boolean recurse) throws IOException
681 {
682 File[] entries=dir.listFiles();
683
684 for (int i=0; entries!=null&&i<entries.length; i++)
685 {
686 File entry=entries[i];
687
688 if (entry.isDirectory()&&recurse)
689 addJars(entry,table,recurse);
690 else
691 {
692 String name=entry.getName().toLowerCase();
693 if (name.endsWith(".jar")||name.endsWith(".zip"))
694 {
695 String jar=entry.getCanonicalPath();
696 if (!table.containsKey(jar))
697 {
698 table.put(jar,jar);
699 boolean added=_classpath.addComponent(jar);
700 if (_debug)
701 System.err.println((added?" CLASSPATH+=":" !")+jar);
702 }
703 }
704 }
705 }
706 }
707 }