package build; import java.lang.reflect.Method; import java.util.Iterator; /** A ClassLoader that will recompile the *.java file corresponding to an out of date or missing *.class file. It also runs rmic to generate *_Stub.class and *_Skel.class files used by RMI.
A single CompilingClassLoader uses a sequence of pairs of directories:
javac -classpath app;jdk/lib/tools.jar -d app
app/build/CompilingClassLoader.java
java -Dbootstrap.path=app/classlib,app/src
-classpath app;jdk/lib/tools.jar
CompilingClassLoader app.Main
The -classpath must provide access to CompilingClassLoader and
tools.jar. It should not contain any directories for classes that
you want recompiled. Specify them in -Dbootstrap.path instead.
When getting a class by name, use CompilingClassLoader.forName() rather than Class.forName(). This will recompile such classes as necessary. **/ public class CompilingClassLoader extends LoadletClassLoader { public CompilingClassLoader(ClassLoader parent, Loadlet loadlet) { super(parent, loadlet); } public static Iterator crack(final String s, final char separator) { return new Iterator() { int start = 0; public boolean hasNext() { return start < s.length(); } public Object next() { int end = s.indexOf(separator, start); end = (end == -1) ? s.length() : end; String result = s.substring(start, end); start = end + 1; return result; } public void remove() {}}; } public static void main(String[] args) { try { Iterator paths = crack(System.getProperty("bootstrap.path", ".,."), ','); Loadlet loadlet = null; while (paths.hasNext()) { String bin = (String) paths.next(); if (paths.hasNext()) { String src = (String) paths.next(); loadlet = new CompilingLoadlet(loadlet, bin, src); } else break; } ClassLoader loader = new CompilingClassLoader (CompilingClassLoader.class.getClassLoader(), loadlet); Class c = loader.loadClass(args[0]); Class[] types = new Class[] { String[].class}; Method m = c.getMethod("main", types); int n = 1; String[] newArgs = new String[args.length - n]; for (int i = 0; i < newArgs.length; i++) newArgs[i] = args[i+n]; Object[] parameters = new Object[] { newArgs }; m.invoke(null, parameters); } catch (Exception e) { e.printStackTrace(); }} }