James Moger
2011-05-04 cf9550d8df51d927c63176675280d69b86e7a6e2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package com.gitblit;
 
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 
/**
 * Launch helper class that adds all jars found in the local "lib" folder and
 * then calls the application main. Using this technique we do not have to
 * specify a classpath and we can dynamically add jars to the distribution.
 * 
 */
public class Launcher {
 
    public final static boolean debug = false;
 
    public static void main(String[] args) {
        if (debug)
            System.out.println("jcp=" + System.getProperty("java.class.path"));
 
        ProtectionDomain protectionDomain = Launcher.class.getProtectionDomain();
        final String launchJar = protectionDomain.getCodeSource().getLocation().toExternalForm();
        if (debug)
            System.out.println("launcher=" + launchJar);
 
        Build.runtime();
 
        // Load the JARs in the lib and ext folder
        String[] folders = new String[] { "lib", "ext" };
        List<File> jars = new ArrayList<File>();
        for (String folder : folders) {
            if (folder == null)
                continue;
            File libFolder = new File(folder);
            if (!libFolder.exists())
                continue;
            try {
                libFolder = libFolder.getCanonicalFile();
            } catch (IOException iox) {
            }
            jars.addAll(findJars(libFolder));
        }
 
        if (jars.size() == 0) {
            for (String folder : folders) {
                File libFolder = new File(folder);
                System.err.println("Failed to find any JARs in " + libFolder.getPath());
            }
            System.exit(-1);
        } else {
            for (File jar : jars) {
                try {
                    addJarFile(jar);
                } catch (Throwable t) {
                    t.printStackTrace();
                }
            }
        }
 
        // Start Server
        GitBlitServer.main(args);
    }
 
    public static List<File> findJars(File folder) {
        List<File> jars = new ArrayList<File>();
        if (folder.exists()) {
            File[] libs = folder.listFiles(new FileFilter() {
                @Override
                public boolean accept(File file) {
                    return !file.isDirectory() && file.getName().toLowerCase().endsWith(".jar");
                }
            });
            if (libs != null && libs.length > 0) {
                jars.addAll(Arrays.asList(libs));
                if (debug) {
                    for (File jar : jars)
                        System.out.println("found " + jar);
                }
            }
        }
        return jars;
    }
 
    /**
     * Parameters of the method to add an URL to the System classes.
     */
    private static final Class<?>[] parameters = new Class[] { URL.class };
 
    /**
     * Adds a file to the classpath
     * 
     * @param f
     *            the file to be added
     * @throws IOException
     */
    public static void addJarFile(File f) throws IOException {
        if (f.getName().indexOf("-sources") > -1 || f.getName().indexOf("-javadoc") > -1) {
            // don't add source or javadoc jars to runtime classpath
            return;
        }
        URL u = f.toURI().toURL();
        if (debug)
            System.out.println("load=" + u.toExternalForm());
        URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
        Class<?> sysclass = URLClassLoader.class;
        try {
            Method method = sysclass.getDeclaredMethod("addURL", parameters);
            method.setAccessible(true);
            method.invoke(sysloader, new Object[] { u });
        } catch (Throwable t) {
            throw new IOException("Error, could not add " + f.getPath() + " to system classloader", t);
        }
    }
}