views:

131

answers:

4

I am looking at Yahoo's YUI compressor executable jar and they have this class, linked from Manifest file as "Main-Class":

package com.yahoo.platform.yui.compressor;

import java.lang.reflect.Method;

public class Bootstrap {

    public static void main(String args[]) throws Exception {
        ClassLoader loader = new JarClassLoader();
        Thread.currentThread().setContextClassLoader(loader);
        Class c = loader.loadClass(YUICompressor.class.getName());
        Method main = c.getMethod("main", new Class[]{String[].class});
        main.invoke(null, new Object[]{args});
    }
}

Which looks like a useless wrapper to me. Why not just directly put YUICompressor as the Main-Class? Is there any reason for doing it this way?

Thanks.

+1  A: 

This seems to be creating a completely new class loader. This is an (imperfect) mechanism for loading independent copies of classes into the same running JVM.

If the YUI stuff uses a lot of static variables, for example, this might be an attempt to work around that, since static variables are per-ClassLoader.

Adam Goode
+1  A: 

Perhaps they wanted to establish the the content ClassLoader for the main thread as one distinct from the default behavior. See the documentation for Thread#getContextClassLoader().

seh
+1  A: 

The active ingredient here is the JarClassLoader. This is able to give your main method a whole new environment where classes and other resources components for the classpath, can be loaded from (probably) out of the jar file the whole thing is running inside of.

This kind of hand-waving is used by schemes like BigJar, which allows you to merge a bunch of jar files into one big (hence the name) executable jar.

And yes, setting up a whole new classloader is practically the only way to accomplish this.

Carl Smotricz
+5  A: 

They are loading YUICompressor using a custom class loader (the new JarClassLoader() piece of code). See YUI Compressor and Java Class Loader for the rationale behind this.

Pascal Thivent