KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > core > Jac


1 /*
2   Copyright (C) 2001-2002 Renaud Pawlak, Laurent Martelli, Lionel Seinturier.
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU Lesser General Public License as
6   published by the Free Software Foundation; either version 2 of the
7   License, or (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12   GNU Lesser General Public License for more details.
13
14   You should have received a copy of the GNU Lesser General Public
15   License along with this program; if not, write to the Free Software
16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17   USA */

18
19 package org.objectweb.jac.core;
20
21
22
23 import java.io.*;
24 import java.io.File JavaDoc;
25 import java.net.URL JavaDoc;
26 import java.net.URLClassLoader JavaDoc;
27 import java.util.*;
28 import org.apache.log4j.ConsoleAppender;
29 import org.apache.log4j.FileAppender;
30 import org.apache.log4j.Level;
31 import org.apache.log4j.Logger;
32 import org.apache.log4j.PatternLayout;
33 import org.objectweb.jac.util.*;
34
35 /**
36  * This is the main class of org.objectweb.jac. It launches a JAC container/server
37  * that is called s0 by default.
38  *
39  * If an application descriptor is given as a last parameter, it runs
40  * the corresponding JAC program on the newly created JAC container by
41  * using a customized class loader <code>JacLoader</code>.
42  *
43  * <p>Use the following command to run <code>MyApp.main()</code> with
44  * <code>arg1, ...</code>:
45  *
46  * <pre>
47  * <b>% java org.objectweb.jac.core.Jac [options] [app.jac arg1, ...]</b>
48  *
49  * where 'app.jac' is a JAC application descriptor
50  *
51  * where options are:
52  * -r (release): JAC displays the release number
53  * -v (verbose): the JAC class loader is set to verbose
54  * -d (debug) : the JAC class loader is set to debugging mode
55  * -c (clean) : JAC cleans the tempory classes directory (previously
56  * created with 'write' option)
57  * -w (write) : the JAC class loader writes on disk all the translated
58  * classes (and use them for the next run)
59  * -V [server:]logname : set the log to verbose mode
60  * -L file : redirect all the logs to a file
61  * -D [name] (dist): JAC runs in distributed mode, i.e. it constructs a
62  * distributed JAC system. If no name is given, the default is s0.
63  * -M [name] : defines a master site where all the bytecode will be
64  * fetched (by default, classes are loaded from the local
65  * file system).
66  * -R dir : specify jac_root directory
67  * -G [gui,...] : launch a list of customized GUI
68  * -G app@server:[gui,...] : launch a list of customized GUIs
69  * with the swing GUI on a remote server for an application
70  * -A name : launches an administration GUI on a remote server called 'name'
71  * and do not start org.objectweb.jac.
72  * -W [gui[:port],...] : start the Web GUI server and provide access to some customized GUIs.
73  * -C <clpath> : specify a particular classpath that will replace $CLASSPATH
74  * -a application aspect server : reload the configuration for an aspect on a server.
75  * -n application aspectClassName server aspectConfPath: create a new aspect on a server.
76  * -u application aspect server : unweave an aspect on a server.
77  * -x : redirect ouput to out.txt
78  * -h (help) : display the help.
79  * </pre>
80  *
81  * @see JacLoader
82  * @author Renaud Pawlak
83  * @author Lionel Seinturier
84  * @author Laurent Martelli */

85
86 public class Jac {
87
88     /** Memorize when the JAC system was launched. */
89     static Date start_time = new Date();
90
91     /**
92      * Returns the JRE version on which JAC is currently running. */

93     public static String JavaDoc getFullJavaVersion() {
94         return System.getProperties().getProperty("java.version");
95     }
96
97     /**
98      * Returns the main JRE version (only the 2 first numbers, e.g. 1.3
99      * or 1.4) on which JAC is currently running. */

100     public static String JavaDoc getMainJavaVersion() {
101         return System.getProperties().getProperty("java.version").substring(0,3);
102     }
103
104     /**
105      * Returns the date when the JAC system was launched.
106      *
107      * @return the date when JAC was launched */

108
109     public static Date getStartTime() {
110         return start_time;
111     }
112
113     /** Verbose flag. */
114     private static boolean verbose = false;
115
116     /** Debug flag (more verbose). */
117     private static boolean debug = false;
118
119     /** Generate flag. */
120     private static boolean gen = false;
121
122     /** Clean flag. JAC cleans the temporary directory of translated
123         class files. */

124     private static boolean clean = false;
125
126     /** Write flag. JAC writes the translated class files into a
127         temporary directory. */

128     private static boolean write = false;
129
130     /** Server flag. JAC is launched in server mode. It waits for
131         remote call and instantiations. */

132     private static boolean server = false;
133
134     /** Client flag. JAC binds to the namespace and the aspect-space. */
135     private static boolean client = false;
136
137     /** Stores the client host name in client or bind mode */
138     private static String JavaDoc clientHost = "";
139
140     /** Stores the server host name in bind mode */
141     private static String JavaDoc serverHost = "";
142
143     /** Stores the master server host name */
144     private static String JavaDoc master = "";
145
146     /** Distributed flag. JAC bootstraps a namespace and an
147         aspect-space on the topology (a set of JAC servers). Then, it
148         launches a deployment program. */

149     private static boolean distributed = false;
150
151     /** Store the class repository container name. */
152     private static String JavaDoc classRepository = "";
153
154     /** Internally used flag, starts a program if true. Set to false if
155         an error occurs when parsing the options. */

156     private static boolean start = true;
157
158     /** The Javassist class loader. */
159     //public static javassist.Loader classLoader;
160
public static JacLoader classLoader;
161
162
163     /** The JAC root directory. */
164     private static String JavaDoc jac_root = "";
165
166     /** The class that is launched when JAC is started. */
167     private static String JavaDoc launchedClass = "";
168
169     /** A flag that tell if the GUI must be started. */
170     private static String JavaDoc[] startSwingGUI = null;
171
172     /** A list of customized GUI IDs to be made available through the WEB */
173     private static String JavaDoc[] startWebGUI = null;
174
175     private static Hashtable logLevels = new Hashtable();
176
177     private static String JavaDoc logFileName;
178
179     /** Stores the server host name in bind mode */
180     private static String JavaDoc remoteGuiServerName = null;
181
182     /** alternative classpath, added with -C option */
183     public static ClassLoader JavaDoc otherClasspath;
184
185     static final String JavaDoc version = "0.12";
186
187     static Logger logger = Logger.getLogger("jac");
188     static Logger perf = Logger.getLogger("perf");
189     static Logger classpath = Logger.getLogger("classpath");
190     static Logger urlloader = Logger.getLogger("urlloader");
191
192     /**
193      * The entry point of the JAC system.
194      *
195      * <p>Creates a JAC loader that will load the classes and translate them.
196      *
197      * @param args the command-line options
198      *
199      * @see JacLoader
200      */

201     public static void main(String JavaDoc[] args) throws Throwable JavaDoc {
202         Logger root = Logger.getRootLogger();
203         root.addAppender(
204             new ConsoleAppender(
205                 new PatternLayout("%d %p %c: %x %m%n")));
206         root.setLevel(Level.WARN);
207         Logger.getLogger("jac").setLevel(Level.INFO);
208         Logger.getLogger("gui").setLevel(Level.INFO);
209         Logger.getLogger("dist").setLevel(Level.INFO);
210         Logger.getLogger("props").setLevel(Level.ERROR);
211         logger.info("JAC version "+version);
212       
213         args = parseOptions(args);
214
215         classLoader = new JacLoader(write, clean, otherClasspath);
216
217         if (remoteGuiServerName!=null) {
218             remoteInvoke(remoteGuiServerName,"launchGUI", new Object JavaDoc[0]);
219             System.exit(0);
220         }
221
222         // launch RMI
223
//Process p = Runtime.getRuntime().exec("rmiregistry");
224
//p.waitFor();//Thread.currentThread().sleep(3000);
225

226         Class JavaDoc daemon = null;
227
228         /** Try to launch a Jac server on the local host */
229         if (!master.equals("")) {
230             try {
231                 ClassLoader JavaDoc cl =
232                     (ClassLoader JavaDoc)Class.forName("org.objectweb.jac.core.dist.DistdClassLoader")
233                     .newInstance ();
234                 Class JavaDoc jac = cl.loadClass("org.objectweb.jac.core.Jac");
235                 jac.getMethod("setJacRoot", new Class JavaDoc[] {String JavaDoc.class}).invoke(
236                     null,new Object JavaDoc[] {jac_root});
237
238                 daemon = cl.loadClass("org.objectweb.jac.core.dist.rmi.RMIDistd");
239                 //System.out.println("-r "+master+" "+serverHost);
240
daemon.getConstructor( new Class JavaDoc[] { String JavaDoc[].class } )
241                     .newInstance ( new Object JavaDoc [] {
242                         new String JavaDoc[] {"-r",master,serverHost} } );
243
244                 Class JavaDoc bootstrap =
245                     cl.loadClass("org.objectweb.jac.aspects.distribution.bootstrap.DistBootstrap");
246                 bootstrap.getMethod("main", new Class JavaDoc[] {String JavaDoc[].class}).invoke(
247                     null,new Object JavaDoc[] {new String JavaDoc[0]});
248
249                 if (start) {
250                     long _start_time = System.currentTimeMillis();
251
252                     ///** start the Aspect Component manager */
253
//classLoader.run ( "org.objectweb.jac.core.ACManager", null );
254
Class JavaDoc acm = cl.loadClass("org.objectweb.jac.core.ACManager");
255                     acm.getMethod("main", new Class JavaDoc[] {String JavaDoc[].class}).invoke(
256                         null,new Object JavaDoc[] {new String JavaDoc[0]});
257
258                     /** runs the application if any */
259                     if (args.length > 0) {
260                         Class JavaDoc appRep = cl.loadClass("org.objectweb.jac.core.ApplicationRepository");
261                         appRep.getMethod("main", new Class JavaDoc[] {String JavaDoc[].class}).invoke(
262                             null,new Object JavaDoc[] {args});
263                     }
264                     perf.info("application started in "+
265                               (System.currentTimeMillis()-_start_time)+"ms");
266                     //Class jacObject = cl.loadClass ( "org.objectweb.jac.core.JacObject" );
267
//jacObject.getMethod("main", new Class[] {String[].class}).invoke(
268
// null,new Object[] {new String[0]});
269
//Semaphore waitingSemaphore = new Semaphore();
270
//waitingSemaphore.acquire();
271
}
272
273             } catch (Exception JavaDoc e) {
274                 System.out.println ("Error: cannot launch Jac server.");
275                 e.printStackTrace();
276                 while (true) {}
277             }
278
279         } else {
280
281             long _start_time = System.currentTimeMillis();
282             if (distributed) {
283                 daemon = classLoader.loadClass("org.objectweb.jac.core.dist.rmi.RMIDistd");
284                 daemon.getConstructor(new Class JavaDoc[] { String JavaDoc[].class })
285                     .newInstance ( new Object JavaDoc [] { new String JavaDoc[] {serverHost} } );
286             }
287             if (client) {
288                 daemon = classLoader.loadClass("org.objectweb.jac.core.dist.rmi.RMIDistd");
289                 daemon.getConstructor(new Class JavaDoc[] { String JavaDoc[].class })
290                     .newInstance ( new Object JavaDoc [] { new String JavaDoc[] { clientHost } } );
291             }
292
293             /*
294               Class jac = classLoader.loadClass ( "org.objectweb.jac.core.Jac" );
295
296               Jac.getMethod( "setJacRoot", new Class[] { String.class } ).invoke(
297               null, new Object[] { jac_root } );
298               if ( startSwingGUI() ) {
299               Jac.getMethod( "setStartSwingGUI", new Class[] {String[].class} ).invoke(
300               null, new Object[] {startSwingGUI} );
301               }
302               if ( startWebGUI() ) {
303               Jac.getMethod( "setStartWebGUI", new Class[] {String[].class} ).invoke(
304               null, new Object[] {startWebGUI} );
305               }
306             */

307
308             if (start) {
309
310                 classLoader.loadClass("org.objectweb.jac.util.Repository");
311                 if (distributed || client || server) {
312                     /** bootstrap the distributed JAC system */
313                     classLoader.run("org.objectweb.jac.aspects.distribution.bootstrap.DistBootstrap", null);
314                 }
315                 //if ( client ) {
316
// /** bind to the distributed JAC system */
317
// classLoader.run("org.objectweb.jac.aspects.distribution.bootstrap.BindClient",
318
// new String[] {clientHost});
319
//}
320
/** start the Aspect Component manager */
321                 classLoader.run("org.objectweb.jac.core.ACManager",null);
322
323                 /** runs the application if any */
324                 if (args.length > 0) {
325                     classLoader.run("org.objectweb.jac.core.ApplicationRepository", args);
326                 }
327                 //classLoader.run ( "org.objectweb.jac.core.JacObject", null );
328
//Semaphore waitingSemaphore = new Semaphore();
329
//waitingSemaphore.acquire();
330
}
331             perf.info("application started in "+
332                       (System.currentTimeMillis()-_start_time)+"ms");
333
334         }
335     }
336
337
338     /**
339      * Transforms a classpath into a list of URLs
340      *
341      * @param path the classpath
342      */

343     private static URL JavaDoc[] parseClasspath(String JavaDoc path)
344     {
345         String JavaDoc[] tab = Strings.splitPath(path);
346
347         URL JavaDoc[] result = new URL JavaDoc[tab.length];
348
349         try {
350             for (int i = 0; i < tab.length; i++) {
351                 urlloader.info("adding "+new File JavaDoc(tab[i]).toURL());
352                 result[i] = new File JavaDoc(tab[i]).toURL();
353             }
354         } catch (Exception JavaDoc e) {
355             e.printStackTrace();
356         }
357
358         return result;
359     }
360
361     /**
362      * Parse the command line and extract the options to set the values
363      * of the appropriate fields.
364      *
365      * @param args the command-line options */

366
367     private static String JavaDoc[] parseOptions(String JavaDoc[] args) {
368         int i = 0;
369         String JavaDoc[] ret = args;
370         if (args.length == 0) {
371             start = false;
372             displayLaunchingHelp();
373             return ret;
374         }
375         try {
376         parse:
377             while((i < args.length) && args[i].startsWith("-")) {
378                 String JavaDoc current =
379                     (args[i].length()>2)
380                     ? args[i].substring(2)
381                     : null;
382                 switch (args[i].charAt(1)) {
383                     case '-':
384                         i++;
385                         break parse;
386                     case 'r':
387                         System.out.println( "- JAC version "+version+" - " +
388                                             "Get new release at http://org.objectweb.jac.aopsys.com/ -" );
389                         break;
390                     case 'v':
391                         verbose = true;
392                         break;
393                     case 'd':
394                         debug = true;
395                         break;
396                     case 'g':
397                         gen = true;
398                         start = false;
399                         break;
400                     case 'w':
401                         write = true;
402                         break;
403                     case 'c':
404                         clean = true;
405                         break;
406                     case 'C': // new Classpath
407
i++;
408                         String JavaDoc[] cp = Strings.splitPath(args[i]);
409                         String JavaDoc newClassPath = "";
410
411                         // transform relative paths into absolute paths
412
for (int j = 0; j < cp.length; j++)
413                         {
414                             File JavaDoc file = new File JavaDoc(cp[j]);
415                             cp[j] = file.getAbsolutePath();
416                             if (newClassPath.length() != 0)
417                                 newClassPath += System.getProperty("path.separator");
418                             newClassPath += cp[j];
419                         }
420
421                         classpath.info("java.class.path="+System.getProperty("java.class.path"));
422                         // reset java.class.path for resources search
423
System.setProperty("java.class.path",
424                                            newClassPath
425                                            + System.getProperty("path.separator")
426                                            + System.getProperty("java.class.path"));
427
428                         otherClasspath =
429                             new URLClassLoader JavaDoc(parseClasspath(newClassPath));
430
431                         break;
432                     case 'D':
433                         distributed = true;
434                         if( (i+1>=args.length) || args[i+1].startsWith("-") ||
435                             args[i+1].endsWith(".jac")) {
436                             serverHost = "s0";
437                         } else {
438                             i++;
439                             serverHost = args[i];
440                         }
441                         break;
442                     case 'M':
443                         i++;
444                         master = args[i];
445                         break;
446                     case 'V':
447                         {
448                             String JavaDoc category = current;
449                             if (category==null) {
450                                 i++;
451                                 category = args[i];
452                             }
453                             int index = category.indexOf(':');
454                             String JavaDoc serverName=null;
455                             if (index!=-1) {
456                                 serverName = category.substring(0,index);
457                                 category = category.substring(index+1);
458                             }
459                             int equalIndex = category.indexOf('=');
460                             Level level = Level.DEBUG;
461                             if (equalIndex!=-1) {
462                                 try {
463                                     level =
464                                         level.toLevel(
465                                             Integer.parseInt(category.substring(equalIndex+1)));
466                                 } catch (NumberFormatException JavaDoc e) {
467                                     level = Level.toLevel(category.substring(equalIndex+1));
468                                 }
469                                 category = category.substring(0,equalIndex);
470                             }
471                             if (serverName!=null) {
472                                 remoteSetTrace("",serverName,category,level.toInt());
473                                 System.exit(0);
474                             } else {
475                                 Logger.getLogger(category).setLevel(level);
476                             }
477                         }
478                         break;
479                     case 'L':
480                         if (current==null) {
481                             i++;
482                             current = args[i];
483                         }
484                         logFileName = current;
485                         Logger.getRootLogger().addAppender(
486                             new FileAppender(
487                                 new PatternLayout(PatternLayout.TTCC_CONVERSION_PATTERN),
488                                 logFileName));
489                         break;
490                     case 'h':
491                         start = false;
492                         displayLaunchingHelp();
493                         break;
494                     case 'R':
495                         i++;
496                         Jac.setJacRoot(args[i]);
497                         break;
498                     case 'G':
499                         {
500                             if (current==null) {
501                                 i++;
502                                 current = args[i];
503                             }
504                             String JavaDoc guis = current;
505                             int index = guis.indexOf(':');
506                             String JavaDoc serverName = null;
507                             if (index!=-1) {
508                                 serverName = guis.substring(0,index);
509                                 guis = guis.substring(index+1);
510                             }
511                             if (serverName==null) {
512                                 Jac.setStartSwingGUI(Strings.split(guis,","));
513                             } else {
514                                 index = serverName.indexOf('@');
515                                 if (index!=-1) {
516                                     remoteStartSwingGUI(serverName.substring(0,index),
517                                                         serverName.substring(index+1),
518                                                         Strings.split(guis,","));
519                                     System.exit(0);
520                                 } else {
521                                     logger.fatal("No application name specified "+
522                                                  "(appName@sever:guiName");
523                                     System.exit(1);
524                                 }
525                             }
526                         }
527                         break;
528                     case 'x':
529                         PrintStream stream =
530                             new PrintStream(new FileOutputStream("out.txt"));
531                         System.setOut(stream);
532                         System.setErr(stream);
533                         break;
534                     case 'A':
535                         i++;
536                         remoteGuiServerName = args[i];
537
538                         start = false;
539                         break;
540                     case 'a':
541                         {
542                             i++;
543                             String JavaDoc applicationName = args[i];
544                             i++;
545                             String JavaDoc aspectName = args[i];
546                             i++;
547                             String JavaDoc serverName = args[i];
548                             remoteReloadAspect(applicationName,serverName,aspectName);
549                             start = false;
550                             System.exit(0);
551                         }
552                         break;
553                     case 'u':
554                         {
555                             i++;
556                             String JavaDoc applicationName = args[i];
557                             i++;
558                             String JavaDoc aspectName = args[i];
559                             i++;
560                             String JavaDoc serverName = args[i];
561                             remoteUnweaveAspect(applicationName,serverName,aspectName);
562                             start = false;
563                             System.exit(0);
564                         }
565                         break;
566                     case 'n':
567                         {
568                             i++;
569                             String JavaDoc applicationName = args[i];
570                             i++;
571                             String JavaDoc aspectName = args[i];
572                             i++;
573                             String JavaDoc serverName = args[i];
574                             i++;
575                             String JavaDoc confPath = args[i];
576                             remoteWeaveAspect(applicationName,serverName,aspectName,confPath);
577                             start = false;
578                             System.exit(0);
579                         }
580                         break;
581                     case 'W':
582                         if (client || server) {
583                             System.out.println("Incompatible options "+
584                                                "(-W, -S, and -C are incompatible)");
585                             displayLaunchingHelp();
586                         }
587                         i++;
588                         Jac.setStartWebGUI(Strings.split(args[i],","));
589                         break;
590                     case 't':
591                         String JavaDoc aspect = args[++i];
592                         String JavaDoc config = args[++i];
593                         try {
594                             ACManager.main(new String JavaDoc [0]);
595                             Logger.getLogger("aspects.config").setLevel(Level.DEBUG);
596                             Logger root = Logger.getRootLogger();
597                             root.removeAllAppenders();
598                             root.addAppender(
599                                 new ConsoleAppender(
600                                     new PatternLayout("%p %m%n")));
601                             AspectComponent ac =
602                                 (AspectComponent)Class.forName(
603                                     ACManager.getACM().getACPathFromName(aspect)).newInstance();
604                             ac.configure(aspect,config);
605                         } catch (Throwable JavaDoc e) {
606                             e.printStackTrace();
607                         }
608                         System.exit(0);
609                         break;
610                     default:
611                         System.out.println("Wrong option: " + args[i]);
612                         displayLaunchingHelp();
613                 }
614                 if (args[i].startsWith("-S")) { i++; break; }
615                 if (args[i].equals("-g")) { break; }
616                 i++;
617             }
618         } catch (Exception JavaDoc e) {
619             e.printStackTrace();
620
621             System.out.println("Error while arguments parsing");
622             displayLaunchingHelp();
623         }
624
625         //if(i == args.length) {
626
//start = false;
627
// return ret;
628
//}
629
if (i>0) {
630             ret = new String JavaDoc[args.length - i];
631             System.arraycopy(args, i, ret, 0, args.length - i);
632         }
633         return ret;
634     }
635
636     /**
637      * Reload an aspect on a remote server
638      * @param application the application for which to reload an aspect
639