By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,028 Members | 1,315 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,028 IT Pros & Developers. It's quick & easy.

Can i unload class in Java

P: 2
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);
}

}
Nov 23 '07 #1
Share this Question
Share on Google+
2 Replies


P: 2
Oupssss

I forgot to tell you, that little application must run with -D<sources path> and -D<binary path> flag on the command line of java.exe

You must have the Tools.jar into the classpath too.

Thanks

inetjack
Nov 23 '07 #2

Expert 10K+
P: 11,448
I don't want to spoil your fun but did you have a look at the JavaCompiler
interface? It's quite new and does the compilation part of what you're trying to
accomplish. It's quite new: >= 1.6

Class objects are supposed to be gc'd be default unless you specify a -X flag:
-Xnoclassgc; if you want to get rid of them on demand you have to write your
own class loader (you can conveniently derive for other loaders).

kind regards,

Jos
Nov 23 '07 #3

Post your reply

Sign in to post your reply or Sign up for a free account.