Hi,
This is a little test application, generating and compiling code at runtime.
The loadClassLoader() method of the Factory Object suppose to unload all class previously loaded.
It does not work!!!
Somebody knows why?
Thanks in advance for your help
inetjack
************************** File Test.java
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.File;
public class Test {
public static void main(String[] args) {
try {
Factory o;
BufferedWriter out;
OneBeans a;
String srcf;
String binf;
o = new Factory("OneBeans");
out = new BufferedWriter(new FileWriter(o.getSrcFile("NewBean")));
out.write("public class NewBean extends OneBeans {\n");
out.write(" public NewBean() {\n");
out.write(" }\n");
out.write("\n");
out.write(" public String getPropString() {\n");
out.write(" return \"Hello World\";\n");
out.write(" }\n");
out.write("\n");
out.write(" public Integer getPropInteger() {\n");
out.write(" return 2;\n");
out.write(" }\n");
out.write("\n");
out.write(" public void otherPrint() {\n");
out.write(" System.out.println(\"otherPrint()\");\n");
out.write(" }\n");
out.write("\n");
out.write(" public void print() {\n");
out.write(" System.out.println(\"NewBean exist!\");\n");
out.write(" }\n");
out.write("}\n");
out.close();
a = o.newInstance("NewBean");
a.print();
System.out.println(a.invoke("getPropString"));
System.out.println(a.invoke("getPropInteger"));
a.invoke("otherPrint");
a = null;
o.loadClassLoader();
srcf = o.getSrcFile("NewBean");
binf = o.getBinFile("NewBean");
System.out.println("delete " + srcf + " = " + (((new File(srcf)).delete()) ? "Yes" : "No"));
System.out.println("delete " + binf + " = " + (((new File(binf)).delete()) ? "Yes" : "No"));
out = new BufferedWriter(new FileWriter(o.getSrcFile("NewBean")));
out.write("public class NewBean extends OneBeans {\n");
out.write(" public NewBean() {\n");
out.write(" }\n");
out.write("\n");
out.write(" public String getPropString() {\n");
out.write(" return \"Hello World Again\";\n");
out.write(" }\n");
out.write("\n");
out.write(" public Integer getPropInteger() {\n");
out.write(" return 22;\n");
out.write(" }\n");
out.write("\n");
out.write(" public void otherPrint() {\n");
out.write(" System.out.println(\"otherPrint()\");\n");
out.write(" }\n");
out.write("\n");
out.write(" public void print() {\n");
out.write(" System.out.println(\"NewBean 2 exist!\");\n");
out.write(" }\n");
out.write("}\n");
out.close();
a = o.newInstance("NewBean");
a.print();
System.out.println(a.invoke("getPropString"));
System.out.println(a.invoke("getPropInteger"));
a.invoke("otherPrint");
a = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
********************** File OneBeans.java
import java.lang.reflect.*;
public abstract class OneBeans {
public abstract void print();
public Object invoke(String methodName, Object[] args)
throws NoSuchMethodException, IllegalAccessException,
InvocationTargetException, ClassNotFoundException {
Class[] c = {};
return this.getClass().getMethod(methodName, c).invoke(this, args);
}
public Object invoke(String methodName)
throws NoSuchMethodException, IllegalAccessException,
InvocationTargetException, ClassNotFoundException {
Object[] args = {};
return invoke(methodName, args);
}
}
*********************** File Factory.java
import java.util.HashMap;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.File;
public class Factory {
private HashMap allClasses;
private String abstractClassName;
private String packageName;
private Class abstractClass;
private MyClassLoader classLoader;
public Factory(String abstractClassName) throws ClassNotFoundException {
this.abstractClassName = abstractClassName;
this.packageName = "";
int lio = abstractClassName.lastIndexOf(".") + 1;
if (lio > 0) {
this.abstractClassName = abstractClassName.substring(lio);
this.packageName = abstractClassName.substring(0, lio);
}
this.loadClassLoader();
}
private void clearAllClasses() {
try {
allClasses.clear();
} catch (Exception e) {
}
}
private String getFileName(String className, boolean src) {
String propName = (src) ? "sources.path" : "bin.path";
String response = (src) ? "java" : "class";
String packPath = this.getPackageName().replace(".","/");
return System.getProperty(propName) + "/" + packPath + className + "." + response;
}
private String compile(String srcFile, String binFile) {
File src = new File(srcFile);
File bin = new File(binFile);
int resultCode = 0;
String result = "";
if (src.lastModified() != bin.lastModified()) {
System.out.println("Compiling " + srcFile + "...");
StringWriter err = new StringWriter();
PrintWriter errPrinter = new PrintWriter(err);
String args[] = {"-classpath",
System.getProperty("java.class.path"),
"-d",
System.getProperty("bin.path"),
"-sourcepath",
System.getProperty("sources.path"),
srcFile};
resultCode = com.sun.tools.javac.Main.compile(args, errPrinter);
errPrinter.close();
result = err.toString();
bin.setLastModified(src.lastModified());
}
return (resultCode == 0) ? null : result;
}
public String getSrcFile(String className) {
return getFileName(className, true);
}
public String getBinFile(String className) {
return getFileName(className, false);
}
public String getPackageName() {
return this.packageName;
}
public String getAbstractClassName() {
return this.abstractClassName;
}
public String getFullAbstractClassName() {
return this.packageName + this.abstractClassName;
}
public String getFullClassName(String className) {
return this.packageName + className;
}
public Class getOneClass(String className) {
return (Class) allClasses.get(className);
}
public OneBeans newInstance(String className)
throws ClassNotFoundException, InstantiationException, IllegalAccessException {
return (OneBeans) this.loadClass(className).newInstance();
}
public void loadClassLoader() throws ClassNotFoundException {
clearAllClasses();
allClasses = null;
this.classLoader = null;
abstractClass = null;
Runtime.getRuntime().gc();
Runtime.getRuntime().gc();
allClasses = new HashMap();
this.classLoader = new MyClassLoader();
abstractClass = this.classLoader.loadOneClass(this.getFullAbstract ClassName(), true);
}
public Class loadClass(String className) throws ClassNotFoundException {
if (allClasses.containsKey(className)) {
return getOneClass(className);
} else {
String result = compile(this.getSrcFile(className), this.getBinFile(className));
if (result == null) {
Class cl = this.classLoader.loadOneClass(this.getFullClassNam e(className), true);
allClasses.put(className, cl);
return cl;
} else {
System.err.println(result);
return null;
}
}
}
}
class MyClassLoader extends ClassLoader {
public Class loadOneClass(String className, boolean resolve) throws ClassNotFoundException {
return this.loadClass(className, resolve);
}
}