KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mortbay > start > Main


1 // ========================================================================
2
// $Id: Main.java,v 1.37 2006/05/27 09:56:58 gregwilkins Exp $
3
// Copyright 2003-2004 Mort Bay Consulting Pty. Ltd.
4
// ------------------------------------------------------------------------
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
// ========================================================================
15
package org.mortbay.start;
16
17 import java.io.BufferedReader JavaDoc;
18 import java.io.File JavaDoc;
19 import java.io.FileInputStream JavaDoc;
20 import java.io.FilenameFilter JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.InputStream JavaDoc;
23 import java.io.InputStreamReader JavaDoc;
24 import java.lang.reflect.InvocationTargetException JavaDoc;
25 import java.lang.reflect.Method JavaDoc;
26 import java.security.Policy JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.Hashtable JavaDoc;
29 import java.util.StringTokenizer JavaDoc;
30
31 /*-------------------------------------------*/
32 /**
33  * Main start class. This class is intended to be the main class listed in the MANIFEST.MF of the
34  * start.jar archive. It allows an application to be started with the command "java -jar
35  * start.jar". The behaviour of Main is controlled by the "org/mortbay/start/start.config" file
36  * obtained as a resource or file. This can be overridden with the START system property. The
37  * format of each line in this file is:
38  *
39  * <PRE>
40  *
41  * SUBJECT [ [!] CONDITION [AND|OR] ]*
42  *
43  * </PRE>
44  *
45  * where SUBJECT:
46  *
47  * <PRE>
48  *
49  * ends with ".class" is the Main class to run. ends with ".xml" is a configuration file for the
50  * command line ends with "/" is a directory from which add all jar and zip files from. ends with
51  * "/*" is a directory from which add all unconsidered jar and zip files from. Containing = are
52  * used to assign system properties. all other subjects are treated as files to be added to the
53  * classpath.
54  *
55  * </PRE>
56  *
57  * Subjects may include system properties with $(propertyname) syntax. File subjects starting with
58  * "/" are considered absolute, all others are relative to the home directory.
59  * <P>
60  * CONDITION is one of:
61  *
62  * <PRE>
63  *
64  * always never available package.class java OPERATOR n.n nargs OPERATOR n OPERATOR := one of "
65  * <",">"," <=",">=","==","!="
66  *
67  * </PRE>
68  *
69  * CONTITIONS can be combined with AND OR or !, with AND being the assume operator for a list of
70  * CONDITIONS. Classpath operations are evaluated on the fly, so once a class or jar is added to
71  * the classpath, subsequent available conditions will see that class. The system parameter
72  * CLASSPATH, if set is given to the start classloader before any paths from the configuration
73  * file. Programs started with start.jar may be stopped with the stop.jar, which connects via a
74  * local port to stop the server. The default port can be set with the STOP.PORT system property (a
75  * port of < 0 disables the stop mechanism). If the STOP.KEY system property is set, then a random
76  * key is generated and written to stdout. This key must be passed to the stop.jar.
77  *
78  * @author Jan Hlavaty (hlavac@code.cz)
79  * @author Greg Wilkins
80  * @version $Revision: 1.37 $
81  */

82 public class Main
83 {
84     static boolean _debug=System.getProperty("DEBUG",null)!=null;
85     private String JavaDoc _classname=null;
86     private Classpath _classpath=new Classpath();
87     private String JavaDoc _config=System.getProperty("START","org/mortbay/start/start.config");
88     private ArrayList JavaDoc _xml=new ArrayList JavaDoc();
89
90     public static void main(String JavaDoc[] args)
91     {
92         try
93         {
94             new Main().start(args);
95         }
96         catch(Exception JavaDoc e)
97         {
98             e.printStackTrace();
99         }
100     }
101
102     static File JavaDoc getDirectory(String JavaDoc name)
103     {
104         try
105         {
106             if(name!=null)
107             {
108                 File JavaDoc dir=new File JavaDoc(name).getCanonicalFile();
109                 if(dir.isDirectory())
110                 {
111                     return dir;
112                 }
113             }
114         }
115         catch(IOException JavaDoc e)
116         {}
117         return null;
118     }
119     
120     boolean isAvailable(String JavaDoc classname)
121     {
122         try
123         {
124             Class.forName(classname);
125             return true;
126         }
127         catch(NoClassDefFoundError JavaDoc e) {}
128         catch(ClassNotFoundException JavaDoc e) {}
129         ClassLoader JavaDoc loader=_classpath.getClassLoader();
130         try
131         {
132             loader.loadClass(classname);
133             return true;
134         }
135         catch(NoClassDefFoundError JavaDoc e) {}
136         catch(ClassNotFoundException JavaDoc e) {}
137         return false;
138     }
139
140     public static void invokeMain(ClassLoader JavaDoc classloader,String JavaDoc classname,String JavaDoc[] args)
141             throws IllegalAccessException JavaDoc,InvocationTargetException JavaDoc,NoSuchMethodException JavaDoc,ClassNotFoundException JavaDoc
142     {
143         Class JavaDoc invoked_class=null;
144         invoked_class=classloader.loadClass(classname);
145         Class JavaDoc[] method_param_types=new Class JavaDoc[1];
146         method_param_types[0]=args.getClass();
147         Method JavaDoc main=null;
148         main=invoked_class.getDeclaredMethod("main",method_param_types);
149         Object JavaDoc[] method_params=new Object JavaDoc[1];
150         method_params[0]=args;
151         main.invoke(null,method_params);
152     }
153
154     /* ------------------------------------------------------------ */
155     String JavaDoc expand(String JavaDoc s)
156     {
157         int i1=0;
158         int i2=0;
159         while(s!=null)
160         {
161             i1=s.indexOf("$(",i2);
162             if(i1<0)
163                 break;
164             i2=s.indexOf(")",i1+2);
165             if(i2<0)
166                 break;
167             String JavaDoc property=System.getProperty(s.substring(i1+2,i2),"");
168             s=s.substring(0,i1)+property+s.substring(i2+1);
169         }
170         return s;
171     }
172
173     /* ------------------------------------------------------------ */
174     void configure(InputStream JavaDoc config,int nargs) throws Exception JavaDoc
175     {
176         BufferedReader JavaDoc cfg=new BufferedReader JavaDoc(new InputStreamReader JavaDoc(config,"ISO-8859-1"));
177         Version java_version=new Version(System.getProperty("java.version"));
178         Version ver=new Version();
179         // JAR's already processed
180
java.util.Hashtable JavaDoc done=new Hashtable JavaDoc();
181         // Initial classpath
182
String JavaDoc classpath=System.getProperty("CLASSPATH");
183         if(classpath!=null)
184         {
185             StringTokenizer JavaDoc tok=new StringTokenizer JavaDoc(classpath,File.pathSeparator);
186             while(tok.hasMoreTokens())
187                 _classpath.addComponent(tok.nextToken());
188         }
189         // Handle line by line
190
String JavaDoc line=null;
191         while(true)
192         {
193             line=cfg.readLine();
194             if(line==null)
195                 break;
196             if(line.length()==0||line.startsWith("#"))
197                 continue;
198             try
199             {
200                 StringTokenizer JavaDoc st=new StringTokenizer JavaDoc(line);
201                 String JavaDoc subject=st.nextToken();
202                 subject=expand(subject);
203                 boolean expression=true;
204                 boolean not=false;
205                 String JavaDoc condition=null;
206                 // Evaluate all conditions
207
while(st.hasMoreTokens())
208                 {
209                     condition=st.nextToken();
210                     if(condition.equalsIgnoreCase("!"))
211                     {
212                         not=true;
213                         continue;
214                     }
215                     if(condition.equalsIgnoreCase("OR"))
216                     {
217                         if(expression)
218                             break;
219                         expression=true;
220                         continue;
221                     }
222                     if(condition.equalsIgnoreCase("AND"))
223                     {
224                         if(!expression)
225                             break;
226                         continue;
227                     }
228                     boolean eval=true;
229                     if(condition.equals("true")||condition.equals("always"))
230                     {
231                         eval=true;
232                     }
233                     else if(condition.equals("false")||condition.equals("never"))
234                     {
235                         eval=false;
236                     }
237                     else if(condition.equals("available"))
238                     {
239                         String JavaDoc class_to_check=st.nextToken();
240                         eval=isAvailable(class_to_check);
241                     }
242                     else if(condition.equals("exists"))
243                     {
244                         try
245                         {
246                             eval=false;
247                             File JavaDoc file=new File JavaDoc(expand(st.nextToken()));
248                             eval=file.exists();
249                         }
250                         catch(Exception JavaDoc e)
251                         {
252                             if(_debug)
253                                 e.printStackTrace();
254                         }
255                     }
256                     else if(condition.equals("property"))
257                     {
258                         String JavaDoc property = System.getProperty(st.nextToken());
259                         eval=property!=null && property.length()>0;
260                     }
261                     else if(condition.equals("java"))
262                     {
263                         String JavaDoc operator=st.nextToken();
264                         String JavaDoc version=st.nextToken();
265                         ver.parse(version);
266                         eval=(operator.equals("<")&&java_version.compare(ver)<0)
267                                 ||(operator.equals(">")&&java_version.compare(ver)>0)
268                                 ||(operator.equals("<=")&&java_version.compare(ver)<=0)
269                                 ||(operator.equals("=<")&&java_version.compare(ver)<=0)
270                                 ||(operator.equals("=>")&&java_version.compare(ver)>=0)
271                                 ||(operator.equals(">=")&&java_version.compare(ver)>=0)
272                                 ||(operator.equals("==")&&java_version.compare(ver)==0)
273                                 ||(operator.equals("!=")&&java_version.compare(ver)!=0);
274                     }
275                     else if(condition.equals("nargs"))
276                     {
277                         String JavaDoc operator=st.nextToken();
278                         int number=Integer.parseInt(st.nextToken());
279                         eval=(operator.equals("<")&&nargs<number)||(operator.equals(">")&&nargs>number)
280                                 ||(operator.equals("<=")&&nargs<=number)||(operator.equals("=<")&&nargs<=number)
281                                 ||(operator.equals("=>")&&nargs>=number)||(operator.equals(">=")&&nargs>=number)
282                                 ||(operator.equals("==")&&nargs==number)||(operator.equals("!=")&&nargs!=number);
283                     }
284                     else
285                     {
286                         System.err.println("ERROR: Unknown condition: "+condition);
287                         eval=false;
288                     }
289                     expression&=not?!eval:eval;
290                     not=false;
291                 }
292                 
293                 String JavaDoc file=subject.replace('/',File.separatorChar);
294                 if(_debug)
295                     System.err.println((expression?"T ":"F ")+line+" subject="+subject);
296                 if(!expression)
297                 {
298                     done.put(file,file);
299                     continue;
300                 }
301                 // Handle the subject
302
if(subject.indexOf("=")>0)
303                 {
304                     int i=file.indexOf("=");
305                     String JavaDoc property=file.substring(0,i);
306                     String JavaDoc value=file.substring(i+1);
307                     if(_debug)
308                         System.err.println(" "+property+"="+value);
309                     System.setProperty(property,value);
310                 }
311                 else if(subject.endsWith("/*"))
312                 {
313                     // directory of JAR files
314
File JavaDoc extdir=new File JavaDoc(file.substring(0,file.length()-1));
315                     File JavaDoc[] jars=extdir.listFiles(new FilenameFilter JavaDoc()
316                     {
317                         public boolean accept(File JavaDoc dir,String JavaDoc name)
318                         {
319                             String JavaDoc namelc=name.toLowerCase();
320                             return namelc.endsWith(".jar")||name.endsWith(".zip");
321                         }
322                     });
323                     for(int i=0;jars!=null&&i<jars.length;i++)
324                     {
325                         String JavaDoc jar=jars[i].getCanonicalPath();
326                         if(!done.containsKey(jar))
327                         {
328                             done.put(jar,jar);
329                             boolean added=_classpath.addComponent(jar);
330                             if(_debug)
331                                 System.err.println((added?" CLASSPATH+=":" !")+jar);
332                         }
333                     }
334                 }
335                 else if(subject.endsWith("/"))
336                 {
337                     // class directory
338
File JavaDoc cd=new File JavaDoc(file);
339                     String JavaDoc d=cd.getCanonicalPath();
340                     if(!done.containsKey(d))
341                     {
342                         done.put(d,d);
343                         boolean added=_classpath.addComponent(d);
344                         if(_debug)
345                             System.err.println((added?" CLASSPATH+=":" !")+d);
346                     }
347                 }
348                 else if(subject.toLowerCase().endsWith(".xml"))
349                 {
350                     // Config file
351
File JavaDoc f=new File JavaDoc(file);
352                     if(f.exists())
353                         _xml.add(f.getCanonicalPath());
354                     if(_debug)
355                         System.err.println(" ARGS+="+f);
356                 }
357                 else if(subject.toLowerCase().endsWith(".class"))
358                 {
359                     // Class
360
String JavaDoc cn=expand(subject.substring(0,subject.length()-6));
361                     if(cn!=null&&cn.length()>0)
362                     {
363                         if(_debug)
364                             System.err.println(" CLASS="+cn);
365                         _classname=cn;
366                     }
367                 }
368                 else if (subject!=null && subject.length()>0)
369                 {
370                     // single JAR file
371
File JavaDoc f=new File JavaDoc(file);
372                     String JavaDoc d=f.getCanonicalPath();
373                     if(!done.containsKey(d))
374                     {
375                         done.put(d,d);
376                         boolean added=_classpath.addComponent(d);
377                         if(!added)
378                         {
379                             added=_classpath.addClasspath(expand(subject));
380                             if(_debug)
381                                 System.err.println((added?" CLASSPATH+=":" !")+d);
382                         }
383                         else if(_debug)
384                             System.err.println((added?" CLASSPATH+=":" !")+d);
385                     }
386                 }
387             }
388             catch(Exception JavaDoc e)
389             {
390                 System.err.println("on line: '"+line+"'");
391                 e.printStackTrace();
392             }
393         }
394     }
395
396     /* ------------------------------------------------------------ */
397     public void start(String JavaDoc[] args)
398     {
399         ArrayList JavaDoc al=new ArrayList JavaDoc();
400         for(int i=0;i<args.length;i++)
401         {
402             if(args[i]==null)
403                 continue;
404             if(args[i].startsWith("-"))
405             {
406                 System.err.println("Usage: java [-DDEBUG] [-DSTART=start.config] [-Dmain.class=org.MyMain] -jar start.jar [--help] [config ...]");
407                 System.exit(1);
408             }
409             else
410                 al.add(args[i]);
411         }
412         args=(String JavaDoc[])al.toArray(new String JavaDoc[al.size()]);
413         // set up classpath:
414
InputStream JavaDoc cpcfg = null;
415         try
416         {
417             Monitor.monitor();
418             
419             cpcfg=getClass().getClassLoader().getResourceAsStream(_config);
420             if(_debug)
421                 System.err.println("config="+_config);
422             if(cpcfg==null)
423                 cpcfg=new FileInputStream JavaDoc(_config);
424             configure(cpcfg,args.length);
425             File JavaDoc file=new File JavaDoc(System.getProperty("jetty.home"));
426             String JavaDoc canonical=file.getCanonicalPath();
427             System.setProperty("jetty.home",canonical);
428         }
429         catch(Exception JavaDoc e)
430         {
431             e.printStackTrace();
432             System.exit(1);
433         }
434         finally
435         {
436             try{cpcfg.close();}
437         catch(Exception JavaDoc e){e.printStackTrace();}
438         }
439         // okay, classpath complete.
440
System.setProperty("java.class.path",_classpath.toString());
441         ClassLoader JavaDoc cl=_classpath.getClassLoader();
442         if(_debug)
443         {
444             System.err.println("java.class.path="+System.getProperty("java.class.path"));
445             System.err.println("jetty.home="+System.getProperty("jetty.home"));
446             System.err.println("java.io.tmpdir="+System.getProperty("java.io.tmpdir"));
447             System.err.println("java.class.path="+_classpath);
448             System.err.println("classloader="+cl);
449             System.err.println("classloader.parent="+cl.getParent());
450         }
451         // Invoke main(args) using new classloader.
452
Thread.currentThread().setContextClassLoader(cl);
453         // re-eval the policy now that env is set
454
try
455         {
456             Policy JavaDoc policy=Policy.getPolicy();
457             if(policy!=null)
458                 policy.refresh();
459         }
460         catch(Exception JavaDoc e)
461         {
462             e.printStackTrace();
463         }
464         try
465         {
466             for(int i=0;i<args.length;i++)
467             {
468                 if(args[i]==null)
469                     continue;
470                 _xml.add(args[i]);
471             }
472             args=(String JavaDoc[])_xml.toArray(args);
473
474             if(_debug)
475                 System.err.println("main.class="+_classname);
476             invokeMain(cl,_classname,args);
477         }
478         catch(Exception JavaDoc e)
479         {
480             e.printStackTrace();
481         }
482     }
483 }
484
Popular Tags