ServerStarter.java 5.89 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * $RCSfile$
 * $Revision: 1089 $
 * $Date: 2005-03-07 02:36:27 -0300 (Mon, 07 Mar 2005) $
 *
 * Copyright (C) 2004 Jive Software. All rights reserved.
 *
 * This software is published under the terms of the GNU Public License (GPL),
 * a copy of which is included in this distribution.
 */

package org.jivesoftware.wildfire.starter;

import org.jivesoftware.util.Log;

Matt Tucker's avatar
Matt Tucker committed
16 17 18
import java.io.*;
import java.util.jar.Pack200;
import java.util.jar.JarOutputStream;
19 20 21 22 23 24 25 26 27 28

/**
 * Starts the core XMPP server. A bootstrap class that configures classloaders
 * to ensure easy, dynamic server startup.
 *
 * This class should be for standalone mode only. Wildfire servers launched
 * through a J2EE container (servlet/EJB) will use those environment's
 * classloading facilities to ensure proper startup.<p>
 *
 * Tasks:<ul>
Matt Tucker's avatar
Matt Tucker committed
29
 *      <li>Unpack any pack files in the lib directory (Pack200 encoded JAR files).</li>
30 31 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
 *      <li>Add all jars in the lib directory to the classpath.</li>
 *      <li>Add the config directory to the classpath for loadResource()</li>
 *      <li>Start the server</li>
 * </ul>
 *
 * Note: if the enviroment property <tt>wildfire.lib.directory</tt> is specified
 * ServerStarter will attempt to use this value as the value for wildfire's lib
 * directory. If the property is not specified the default value of ../lib will be used.
 *
 * @author Iain Shigeoka
 */
public class ServerStarter {

    /**
     * Default to this location if one has not been specified
     */
    private static final String DEFAULT_LIB_DIR = "../lib";

    public static void main(String [] args) {
        new ServerStarter().start();
    }

    /**
     * Starts the server by loading and instantiating the bootstrap
     * container. Once the start method is called, the server is
     * started and the server starter should not be used again.
     */
    private void start() {
58
        // Setup the classpath using JiveClassLoader
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
        try {
            // Load up the bootstrap container
            final ClassLoader parent = findParentClassLoader();

            String libDirString = System.getProperty("wildfire.lib.dir");

            File libDir;
            if (libDirString != null) {
                // If the lib directory property has been specified and it actually
                // exists use it, else use the default
                libDir = new File(libDirString);
                if (!libDir.exists()) {
                    Log.warn("Lib directory " + libDirString +
                            " does not exist. Using default " + DEFAULT_LIB_DIR);
                    libDir = new File(DEFAULT_LIB_DIR);
                }
            }
            else {
                libDir = new File(DEFAULT_LIB_DIR);
            }

Matt Tucker's avatar
Matt Tucker committed
80 81 82
            // Unpack any pack files.
            unpackArchives(libDir);

83
            ClassLoader loader = new JiveClassLoader(parent, libDir);
Matt Tucker's avatar
Matt Tucker committed
84

85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
            Thread.currentThread().setContextClassLoader(loader);
            Class containerClass = loader.loadClass(
                    "org.jivesoftware.wildfire.XMPPServer");
            containerClass.newInstance();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Locates the best class loader based on context (see class description).
     *
     * @return The best parent classloader to use
     */
    private ClassLoader findParentClassLoader() {
        ClassLoader parent = Thread.currentThread().getContextClassLoader();
        if (parent == null) {
            parent = this.getClass().getClassLoader();
            if (parent == null) {
                parent = ClassLoader.getSystemClassLoader();
            }
        }
        return parent;
    }
Matt Tucker's avatar
Matt Tucker committed
110

Matt Tucker's avatar
Matt Tucker committed
111 112 113 114 115 116 117
    /**
     * Converts any pack files in a directory into standard JAR files. Each
     * pack file will be deleted after being converted to a JAR. If no
     * pack files are found, this method does nothing.
     *
     * @param libDir the directory containing pack files.
     */
Matt Tucker's avatar
Matt Tucker committed
118 119 120 121 122 123 124
    private void unpackArchives(File libDir) {
        // Get a list of all packed files in the lib directory.
        File [] packedFiles = libDir.listFiles(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return name.endsWith(".pack");
            }
        });
125 126 127 128 129 130

        if (packedFiles == null) {
            // Do nothing since no .pack files were found
            return;
        }

Matt Tucker's avatar
Matt Tucker committed
131 132 133 134 135 136
        // Unpack each.
        boolean unpacked = false;
        for (File packedFile : packedFiles) {
            try {
                String jarName = packedFile.getName().substring(0,
                        packedFile.getName().length() - ".pack".length());
137 138 139 140 141 142 143
                // Delete JAR file with same name if it exists (could be due to upgrade
                // from old Wildfire release).
                File jarFile = new File(libDir, jarName);
                if (jarFile.exists()) {
                    jarFile.delete();
                }
                
Matt Tucker's avatar
Matt Tucker committed
144 145 146 147
                InputStream in = new BufferedInputStream(new FileInputStream(packedFile));
                JarOutputStream out = new JarOutputStream(new BufferedOutputStream(
                        new FileOutputStream(new File(libDir, jarName))));
                Pack200.Unpacker unpacker = Pack200.newUnpacker();
Matt Tucker's avatar
Matt Tucker committed
148
                // Print something so the user knows something is happening.
Matt Tucker's avatar
Matt Tucker committed
149 150 151 152 153 154
                System.out.print(".");
                // Call the unpacker
                unpacker.unpack(in, out);

                in.close();
                out.close();
Matt Tucker's avatar
Matt Tucker committed
155
                packedFile.delete();
Matt Tucker's avatar
Matt Tucker committed
156 157 158
                unpacked = true;
            }
            catch (Exception e) {
Matt Tucker's avatar
Matt Tucker committed
159
                Log.error(e);
Matt Tucker's avatar
Matt Tucker committed
160 161
            }
        }
Matt Tucker's avatar
Matt Tucker committed
162
        // Print newline if unpacking happened.
Matt Tucker's avatar
Matt Tucker committed
163
        if (unpacked) {
Matt Tucker's avatar
Matt Tucker committed
164
            System.out.println();
Matt Tucker's avatar
Matt Tucker committed
165 166
        }
    }
167
}