On Oct 14, 12:17 pm, "Aryeh M. Friedman" <Aryeh.Fried...@gmail.com>
On Oct 14, 6:01 pm, Steven Simpson <s...@domain.invalid> wrote:
Aryeh M. Friedman wrote:
Then how do you handle the return type?!?!?!? Namely I can't do:
Class<?> testClass = loadTestClass();
Object testInstance = testClass.newInstance();
Result res=new Result();
for (Method method: testClass.getDeclaredMethods())
res.merge((Result) method.invoke(testInstance, new
Object[0])); // cast exception
The reason why it is not possible is any Result object created by a
test is <MyClassLoader>.Result and all the results here are
<SystemClassLoader>.Result
Looking back at an earlier post, your custom MyClassLoader goes like this:
public class MyClassLoader extends ClassLoader
{
public Class loadClass(String name)
{
try {
if(name.startsWith("java."))
return super.loadClass(name);
A custom ClassLoader is expected to override findClass(String) rather
than loadClass(String), as the latter (indirectly) accomplishes this
behaviour:
<http://java.sun.com/javase/6/docs/api/java/lang/ClassLoader.html>
"When requested to find a class or resource, a ClassLoader instance will
delegate the search for the class or resource to its parent class loader
before attempting to find the class or resource itself."
MyClassLoader is loading Result instead of delegating to its parent
first, which should always find it first.
I just tested:import java.io.*;
import java.lang.reflect.*;
public class MyClassLoader extends ClassLoader
{
public Class findClass(String name)
{
try {
//if(name.startsWith("java."))
// return super.loadClass(name);
FileInputStream fis=new FileInputStream(name
+".class");
byte[] b=new byte[fis.available()];
fis.read(b);
fis.close();
return defineClass(name,b,0,b.length);
} catch(Throwable e) {
e.printStackTrace();
}
return null;
}
and now the class loader no longer honors recompiled classes:
Script started on Sun Oct 14 15:09:05 2007
jtest@monster:/home/jtest% java Main
1
^Z
Suspended
jtest@monster:/home/jtest% cat foo
import java.lang.reflect.*;
public class MyClass
{
public MyClass()
{
ack=new Integer(2);
}
public Integer getAck()
{
return ack;
}
private int foo;
private Integer ack;}
jtest@monster:/home/jtest% cp foo MyClass.java
jtest@monster:/home/jtest% javac MyClass.java
jtest@monster:/home/jtest% fg
java Main
1
^C
jtest@monster:/home/jtest% exit
Script ends on Sun Oct 14 15:09:45 2007
Just for ref here is the new main():
public class Main
{
public static void main(String[] args)
throws Throwable
{
while(true) {
ClassLoader loader=new MyClassLoader();
Class klass=loader.loadClass("MyClass");
MyClass m=(MyClass) klass.newInstance();
System.out.println(m.getAck());
System.in.read();
}
}
}
and your reloadable class wont.