KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > Main


1 /*
2  * JBoss, Home of Professional Open Source
3  * Copyright 2005, JBoss Inc., and individual contributors as indicated
4  * by the @authors tag. See the copyright.txt in the distribution for a
5  * full listing of individual contributors.
6  *
7  * This is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * This software is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this software; if not, write to the Free
19  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21  */

22 package org.jboss;
23
24 import gnu.getopt.Getopt;
25 import gnu.getopt.LongOpt;
26
27 import java.io.File JavaDoc;
28 import java.io.FilenameFilter JavaDoc;
29 import java.net.MalformedURLException JavaDoc;
30 import java.net.URL JavaDoc;
31 import java.net.URLDecoder JavaDoc;
32 import java.util.LinkedList JavaDoc;
33 import java.util.List JavaDoc;
34 import java.util.Properties JavaDoc;
35
36 import org.jboss.system.server.Server;
37 import org.jboss.system.server.ServerConfig;
38 import org.jboss.system.server.ServerConfigUtil;
39 import org.jboss.system.server.ServerLoader;
40
41 /**
42  * Provides a command line interface to start the JBoss server.
43  *
44  * <p>
45  * To enable debug or trace messages durring boot change the Log4j
46  * configuration to use either <tt>log4j-debug.properties</tt>
47  * <tt>log4j-trace.properties</tt> by setting the system property
48  * <tt>log4j.configuration</tt>:
49  *
50  * <pre>
51  * ./run.sh -Dlog4j.configuration=log4j-debug.properties
52  * </pre>
53  * TODO: Should jdk logging be the default
54  *
55  * @author <a HREF="mailto:marc.fleury@jboss.org">Marc Fleury</a>
56  * @author <a HREF="mailto:jason@planet57.com">Jason Dillon</a>
57  * @author <a HREF="mailto:adrian.brock@happeningtimes.com">Adrian Brock</a>
58  * @author Scott.Stark@jboss.org
59  * @version $Revision: 57108 $
60  */

61 public class Main
62 {
63    /** EDU.oswego.cs.dl.util.concurrent */
64    private String JavaDoc concurrentLib = "concurrent.jar";
65
66    /** A URL for obtaining microkernel patches */
67    private URL JavaDoc bootURL;
68    
69    /** Extra jars from the /lib location that are added to the start of the boot
70     classpath. This can be used to override jboss /lib boot classes.
71     */

72    private List JavaDoc bootLibraries = new LinkedList JavaDoc();
73
74    /** Extra libraries to load the server with .*/
75    private List JavaDoc extraLibraries = new LinkedList JavaDoc();
76
77    /** Extra classpath URLS to load the server with .*/
78    private List JavaDoc extraClasspath = new LinkedList JavaDoc();
79
80    /**
81     * Server properties. This object holds all of the required
82     * information to get the server up and running. Use System
83     * properties for defaults.
84     */

85    private Properties JavaDoc props = new Properties JavaDoc(System.getProperties());
86    /** The booted server instance */
87    private Server server;
88
89    /**
90     * Explicit constructor.
91     */

92    public Main()
93    {
94       super();
95    }
96
97    /**
98     * Access the booted server.
99     * @return the Server instance.
100     */

101    public Server getServer()
102    {
103       return server;
104    }
105
106    /**
107     * Boot up JBoss.
108     *
109     * @param args The command line arguments.
110     *
111     * @throws Exception Failed to boot.
112     */

113    public void boot(final String JavaDoc[] args) throws Exception JavaDoc
114    {
115       // First process the command line to pickup custom props/settings
116
processCommandLine(args);
117
118       // Auto set HOME_DIR to ../bin/run.jar if not set
119
String JavaDoc homeDir = props.getProperty(ServerConfig.HOME_DIR);
120       if (homeDir == null)
121       {
122          String JavaDoc path = Main.class.getProtectionDomain().getCodeSource().getLocation().getFile();
123          /* The 1.4 JDK munges the code source file with URL encoding so run
124           * this path through the decoder so that is JBoss starts in a path with
125           * spaces we don't come crashing down.
126          */

127          path = URLDecoder.decode(path, "UTF-8");
128          File JavaDoc runJar = new File JavaDoc(path);
129          File JavaDoc homeFile = runJar.getParentFile().getParentFile();
130          homeDir = homeFile.getCanonicalPath();
131       }
132       props.setProperty(ServerConfig.HOME_DIR, homeDir);
133
134       // Setup HOME_URL too, ServerLoader needs this
135
String JavaDoc homeURL = props.getProperty(ServerConfig.HOME_URL);
136       if (homeURL == null)
137       {
138          File JavaDoc file = new File JavaDoc(homeDir);
139          homeURL = file.toURL().toString();
140          props.setProperty(ServerConfig.HOME_URL, homeURL);
141       }
142
143       // Load the server instance
144
ServerLoader loader = new ServerLoader(props);
145
146       /* If there is a patch dir specified make it the first element of the
147       loader bootstrap classpath. If its a file url pointing to a dir, then
148       add the dir and its contents.
149       */

150       if (bootURL != null)
151       {
152          if (bootURL.getProtocol().equals("file"))
153          {
154             File JavaDoc dir = new File JavaDoc(bootURL.getFile());
155             if (dir.exists())
156             {
157                // Add the local file patch directory
158
loader.addURL(dir.toURL());
159
160                // Add the contents of the directory too
161
File JavaDoc[] jars = dir.listFiles(new JarFilter());
162
163                for (int j = 0; jars != null && j < jars.length; j++)
164                {
165                   loader.addURL(jars[j].getCanonicalFile().toURL());
166                }
167             }
168          }
169          else
170          {
171             loader.addURL(bootURL);
172          }
173       }
174
175       // Add any extra libraries
176
for (int i = 0; i < bootLibraries.size(); i++)
177       {
178          loader.addLibrary((String JavaDoc)bootLibraries.get(i));
179       }
180
181       // Add the jars from the endorsed dir
182
loader.addEndorsedJars();
183
184       // Add jmx libs
185
//loader.addLibraries(jmxLibs);
186

187       // jmx UnifiedLoaderRepository needs a concurrent class...
188
loader.addLibrary(concurrentLib);
189
190       // Add any extra libraries after the boot libs
191
for (int i = 0; i < extraLibraries.size(); i++)
192       {
193          loader.addLibrary((String JavaDoc)extraLibraries.get(i));
194       }
195
196       // Add any extra classapth URLs
197
for (int i = 0; i < extraClasspath.size(); i++)
198       {
199          loader.addURL((URL JavaDoc)extraClasspath.get(i));
200       }
201
202       // Load the server
203
ClassLoader JavaDoc parentCL = Thread.currentThread().getContextClassLoader();
204       server = loader.load(parentCL);
205
206       // Initialize the server
207
server.init(props);
208
209       // Start 'er up mate!
210
server.start();
211    }
212
213    /**
214     * Shutdown the booted Server instance.
215     *
216     */

217    public void shutdown()
218    {
219       server.shutdown();
220    }
221
222    private URL JavaDoc makeURL(String JavaDoc urlspec) throws MalformedURLException JavaDoc
223    {
224       urlspec = urlspec.trim();
225
226       URL JavaDoc url;
227
228       try
229       {
230          url = new URL JavaDoc(urlspec);
231          if (url.getProtocol().equals("file"))
232          {
233             // make sure the file is absolute & canonical file url
234
File JavaDoc file = new File JavaDoc(url.getFile()).getCanonicalFile();
235             url = file.toURL();
236          }
237       }
238       catch (Exception JavaDoc e)
239       {
240          // make sure we have a absolute & canonical file url
241
try
242          {
243             File JavaDoc file = new File JavaDoc(urlspec).getCanonicalFile();
244             url = file.toURL();
245          }
246          catch (Exception JavaDoc n)
247          {
248             throw new MalformedURLException JavaDoc(n.toString());
249          }
250       }
251
252       return url;
253    }
254
255    /** Process the command line... */
256    private void processCommandLine(final String JavaDoc[] args) throws Exception JavaDoc
257    {
258       // set this from a system property or default to jboss
259
String JavaDoc programName = System.getProperty("program.name", "jboss");
260       String JavaDoc sopts = "-:hD:d:p:n:c:Vj::B:L:C:P:b:g:u:l:";
261       LongOpt[] lopts =
262       {
263          new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'),
264          new LongOpt("bootdir", LongOpt.REQUIRED_ARGUMENT, null, 'd'),
265          new LongOpt("patchdir", LongOpt.REQUIRED_ARGUMENT, null, 'p'),
266          new LongOpt("netboot", LongOpt.REQUIRED_ARGUMENT, null, 'n'),
267          new LongOpt("configuration", LongOpt.REQUIRED_ARGUMENT, null, 'c'),
268          new LongOpt("version", LongOpt.NO_ARGUMENT, null, 'V'),
269          new LongOpt("jaxp", LongOpt.REQUIRED_ARGUMENT, null, 'j'),
270          new LongOpt("bootlib", LongOpt.REQUIRED_ARGUMENT, null, 'B'),
271          new LongOpt("library", LongOpt.REQUIRED_ARGUMENT, null, 'L'),
272          new LongOpt("classpath", LongOpt.REQUIRED_ARGUMENT, null, 'C'),
273          new LongOpt("properties", LongOpt.REQUIRED_ARGUMENT, null, 'P'),
274          new LongOpt("host", LongOpt.REQUIRED_ARGUMENT, null, 'b'),
275          new LongOpt("partition", LongOpt.REQUIRED_ARGUMENT, null, 'g'),
276          new LongOpt("udp", LongOpt.REQUIRED_ARGUMENT, null, 'u'),
277          new LongOpt("log", LongOpt.REQUIRED_ARGUMENT, null, 'l'),
278       };
279
280       Getopt getopt = new Getopt(programName, args, sopts, lopts);
281       int code;
282       String JavaDoc arg;
283       props.setProperty(ServerConfig.SERVER_BIND_ADDRESS, "0.0.0.0");
284       System.setProperty(ServerConfig.SERVER_BIND_ADDRESS, "0.0.0.0");
285       while ((code = getopt.getopt()) != -1)
286       {
287          switch (code)
288          {
289             case ':':
290             case '?':
291                // for now both of these should exit with error status
292
System.exit(1);
293                break; // for completeness
294

295             case 1:
296                // this will catch non-option arguments
297
// (which we don't currently care about)
298
System.err.println(programName +
299                                   ": unused non-option argument: " +
300                                   getopt.getOptarg());
301                break; // for completeness
302

303             case 'h':
304                // show command line help
305
System.out.println("usage: " + programName + " [options]");
306                System.out.println();
307                System.out.println("options:");
308                System.out.println(" -h, --help Show this help message");
309                System.out.println(" -V, --version Show version information");
310                System.out.println(" -- Stop processing options");
311                System.out.println(" -D<name>[=<value>] Set a system property");
312                System.out.println(" -d, --bootdir=<dir> Set the boot patch directory; Must be absolute or url");
313                System.out.println(" -p, --patchdir=<dir> Set the patch directory; Must be absolute or url");
314                System.out.println(" -n, --netboot=<url> Boot from net with the given url as base");
315                System.out.println(" -c, --configuration=<name> Set the server configuration name");
316                System.out.println(" -B, --bootlib=<filename> Add an extra library to the front bootclasspath");
317                System.out.println(" -L, --library=<filename> Add an extra library to the loaders classpath");
318                System.out.println(" -C, --classpath=<url> Add an extra url to the loaders classpath");
319                System.out.println(" -P, --properties=<url> Load system properties from the given url");
320                System.out.println(" -b, --host=<host or ip> Bind address for all JBoss services");
321                System.out.println(" -g, --partition=<name> HA Partition name (default=DefaultDomain)");
322                System.out.println(" -u, --udp=<ip> UDP multicast address");
323                System.out.println(" -l, --log=<log4j|jdk> Specify the logger plugin type");
324                System.out.println();
325                System.exit(0);
326                break; // for completeness
327

328             case 'D':
329             {
330                // set a system property
331
arg = getopt.getOptarg();
332                String JavaDoc name, value;
333                int i = arg.indexOf("=");
334                if (i == -1)
335                {
336                   name = arg;
337                   value = "true";
338                }
339                else
340                {
341                   name = arg.substring(0, i);
342                   value = arg.substring(i + 1, arg.length());
343                }
344                System.setProperty(name, value);
345                // Ensure setting the old bind.address property also sets the new
346
// jgroups.bind_addr property, otherwise jgroups may ignore it
347
if ("bind.address".equals(name))
348                {
349                   System.setProperty("jgroups.bind_addr", value);
350                }
351                break;
352             }
353
354             case 'd':
355                // set the boot patch URL
356
bootURL = makeURL(getopt.getOptarg());
357                break;
358
359             case 'p':
360             {
361                // set the patch URL
362
URL JavaDoc patchURL = makeURL(getopt.getOptarg());
363                props.put(ServerConfig.PATCH_URL, patchURL.toString());
364
365                break;
366             }
367
368             case 'n':
369                // set the net boot url
370
arg = getopt.getOptarg();
371
372                // make sure there is a trailing '/'
373
if (!arg.endsWith("/")) arg += "/";
374
375                props.put(ServerConfig.HOME_URL, new URL JavaDoc(arg).toString());
376                break;
377
378             case 'c':
379                // set the server name
380
arg = getopt.getOptarg();
381                props.put(ServerConfig.SERVER_NAME, arg);
382                break;
383
384             case 'V':
385             {
386                // Package information for org.jboss
387
Package JavaDoc jbossPackage = Package.getPackage("org.jboss");
388
389                // show version information
390
System.out.println("JBoss " + jbossPackage.getImplementationVersion());
391                System.out.println();
392                System.out.println("Distributable under LGPL license.");
393                System.out.println("See terms of license at gnu.org.");
394                System.out.println();
395                System.exit(0);
396                break; // for completness
397
}
398
399             case 'j':
400                // Show an error and exit
401
System.err.println(programName + ": option '-j, --jaxp' no longer supported");
402                System.exit(1);
403                break; // for completness
404

405             case 'B':
406                arg = getopt.getOptarg();
407                bootLibraries.add(arg);
408                break;
409
410             case 'L':
411                arg = getopt.getOptarg();
412                extraLibraries.add(arg);
413                break;
414
415             case 'C':
416             {
417                URL JavaDoc url = makeURL(getopt.getOptarg());
418                extraClasspath.add(url);
419                break;
420             }
421
422             case 'P':
423             {
424                // Set system properties from url/file
425
URL JavaDoc url = makeURL(getopt.getOptarg());
426                Properties JavaDoc props = System.getProperties();
427                props.load(url.openConnection().getInputStream());
428                break;
429             }
430             case 'b':
431                arg = getopt.getOptarg();
432                props.put(ServerConfig.SERVER_BIND_ADDRESS, arg);
433                System.setProperty(ServerConfig.SERVER_BIND_ADDRESS, arg);
434                // used by JGroups; only set if not set via -D so users
435
// can use a different interface for cluster communication
436
// There are 2 versions of this property, deprecated bind.address
437
// and the new version, jgroups.bind_addr
438
String JavaDoc bindAddress = System.getProperty("bind.address");
439                if (bindAddress == null)
440                {
441                   System.setProperty("bind.address", arg);
442                }
443                bindAddress = System.getProperty("jgroups.bind_addr");
444                if (bindAddress == null)
445                {
446                   System.setProperty("jgroups.bind_addr", arg);
447                }
448                // Set the java.rmi.server.hostname if not set
449
String JavaDoc rmiHost = System.getProperty("java.rmi.server.hostname");
450                if( rmiHost == null )
451                {
452                   rmiHost = ServerConfigUtil.fixRemoteAddress(arg);
453                   System.setProperty("java.rmi.server.hostname", rmiHost);
454                }
455                break;
456             case 'g':
457                arg = getopt.getOptarg();
458                props.put(ServerConfig.PARTITION_NAME_PROPERTY, arg);
459                System.setProperty(ServerConfig.PARTITION_NAME_PROPERTY, arg);
460                break;
461             case 'u':
462                arg = getopt.getOptarg();
463                props.put(ServerConfig.PARTITION_UDP_PROPERTY, arg);
464                System.setProperty(ServerConfig.PARTITION_UDP_PROPERTY, arg);
465                // the new jgroups property name
466
System.setProperty("jgroups.udp.mcast_addr", arg);
467                break;
468             case 'l':
469             {
470                arg = getopt.getOptarg();
471                String JavaDoc logPlugin = arg;
472                if( arg.equalsIgnoreCase("log4j") )
473                   logPlugin = "org.jboss.logging.Log4jLoggerPlugin";
474                else if( arg.equalsIgnoreCase("jdk") )
475                {
476                   logPlugin = "org.jboss.logging.JDK14LoggerPlugin";
477                   // Also override the jdk LogManager
478
System.setProperty("java.util.logging.manager",
479                      "org.jboss.logging.jdk.JDKLogManager");
480                }
481                System.setProperty("org.jboss.logging.Logger.pluginClass", logPlugin);
482                break;
483             }
484             default:
485                // this should not happen,
486
// if it does throw an error so we know about it
487
throw new Error JavaDoc("unhandled option code: " + code);
488          }
489       }
490    }
491
492    /**
493     * This is where the magic begins.
494     *
495     * <P>Starts up inside of a "jboss" thread group to allow better
496     * identification of JBoss threads.
497     *
498     * @param args The command line arguments.
499     */

500    public static void main(final String JavaDoc[] args) throws Exception JavaDoc
501    {
502       Runnable JavaDoc worker = new Runnable JavaDoc() {
503             public void run()
504             {
505                try
506                {
507                   Main main = new Main();
508                   main.boot(args);
509                }
510                catch (Exception JavaDoc e)
511                {
512                   System.err.println("Failed to boot JBoss:");
513                   e.printStackTrace();
514                }
515             }
516
517          };
518
519       ThreadGroup JavaDoc threads = new ThreadGroup JavaDoc("jboss");
520       new Thread JavaDoc(threads, worker, "main").start();
521    }
522
523    /**
524     * This method is here so that if JBoss is running under
525     * Alexandria (An NT Service Installer), Alexandria can shutdown
526     * the system down correctly.
527     */

528    public static void systemExit(String JavaDoc argv[])
529    {
530       System.exit(0);
531    }
532
533    static class JarFilter implements FilenameFilter JavaDoc
534    {
535       public boolean accept(File JavaDoc dir, String JavaDoc name)
536       {
537          return name.endsWith(".jar");
538       }
539    }
540 }
Popular Tags