
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
import java.util.jar.*;
import java.lang.reflect.*;

public class Test2 {

	public static void main(String[] args) {
		Test2 test2 = new Test2();
		test2.run();
	}

	private void run() {
		try {
			MyAntClassLoader macl = new MyAntClassLoader();
			System.out.println("Successfully instantiated MyAntClassLoader.");
			Class launcherClass = macl.loadClass("org.apache.tools.ant.Project");
			System.out.println("Loaded Project class.");
		} catch (Exception e) {
			System.out.println("This friendly error message is brought to you");
			System.out.println("\tby 'Test2.java'\n");
			e.printStackTrace();
		}
	}

	class MyAntClassLoader extends ClassLoader {

		public MyAntClassLoader() {
			super();
		}

		protected Class findClass(String name) throws ClassNotFoundException, IllegalArgumentException {

			try {
				String className = name.replace('.', '/') + ".class";
				String jarFile = "ant.jar";
				System.out.println("Looking for " + className + " in " + jarFile);
				int maxBytes = findJar(jarFile);
				if (maxBytes > 0)
				{
					JarInputStream jarStream = new JarInputStream(new FileInputStream(jarFile));
					JarEntry entry;
					int entrySize;
					while ((entry = jarStream.getNextJarEntry()) != null)
					{
						if (entry.getName().equals(className))
						{
							System.out.println("Found class " + className + " in " + jarFile + "!!!");
							System.out.println("Actual name is: " + name);
							byte [] classBytes = new byte[maxBytes];
							jarStream.read(classBytes);
							jarStream.closeEntry();
							entrySize = (int)entry.getSize();
							System.out.println("Could have read " + maxBytes + " bytes, but");
							System.out.println("\tactually only read " + entrySize + ".\n");
							return defineClass(name, classBytes, 0, maxBytes);
						}
					}
				}
			} catch (Exception e) {
				System.out.println("This friendly error message is brought to you");
				System.out.println("\tby the inner class MyAntClassLoader.\n");
				throw new ClassNotFoundException(name);
			}
			return null;
		}

		private int findJar(String jarPath) throws IOException, FileNotFoundException
		{
			Integer classBytes;
			int entrySize		= 0;
			int maxEntrySize	= 0;

			File jarFile = new File(jarPath);
			if (jarFile.exists())
			{
				JarInputStream jarStream = new JarInputStream(new FileInputStream(jarPath));
				JarEntry tmpJarEntry;
				while ((tmpJarEntry = jarStream.getNextJarEntry()) != null)
				{
					jarStream.closeEntry();
					entrySize = (int)tmpJarEntry.getSize();
					maxEntrySize = entrySize > maxEntrySize ? entrySize : maxEntrySize;
				}
				jarStream.close();

				classBytes = new Integer(maxEntrySize);
				return classBytes.intValue();
			}
			else return 0;
		}

	}
}