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