Vlad Vidac
Vlad Vidac

Reputation: 998

Using double-reflected objects

What I'm basically trying to do is invoke a method on an object whose class is written in a String and compiled through javax.tools.JavaCompiler
That part is "easy", I've used something similar to this: https://sites.google.com/site/malenkov/java/081217

However, the object I want to invoke a method on is a field in a different class also written in a String and compiled through JavaCompiler. What I have is:

MemoryClassLoader mcl1 = new MemoryClassLoader("Class1", Class1Content);
MemoryClassLoader mcl2 = new MemoryClassLoader("Class2", Class2Content);
Class c1 = mcl1.loadClass("Class1");
Class c2 = mcl2.loadClass("Class2");
Field f = c1.getDeclaredField("current"); //current should be of type Class2
Object obj = f.get(c2.newInstance()); //trying to cast the Field to type Class2 so I can invoke Class2 methods on it
Method m = c2.getDeclaredMethod("Class2Method");
System.out.println(m.invoke(obj));

Important code in Class1 (aka in String variable Class1Content):

Class1Content = "public MemoryClassLoader mcl = new MemoryClassLoader(\"" + "Class2" + "\", Class2Content);\n" +
                "Class c = mcl.loadClass(\"" + "Class2" + "\");\n" +
                "public Object current;\n" + //the object I will try to invoke a method on
                "public Class1()throws Exception{\n" +
                "Field f = c.getDeclaredField(\"initialState\");" + // initialState is the name of the field in Class2 I'm trying to have in Class1
                "current = f.get(c.newInstance()); c.cast(current);\n" +
                "}\n";

When I try to run the first block of code I get an exception at line Object state = f.get(c2.newInstance());

Exception in thread "main" java.lang.IllegalArgumentException: Can not set java.lang.Object field Class1.current to Class2

Is there any way I can do what I'm trying to achieve or do I have to go back to the drawing board?
Thanks!

Upvotes: 1

Views: 90

Answers (1)

Neil Masson
Neil Masson

Reputation: 2689

MemoryClassLoader extends ClassLoader, so your two classes are loaded with different ClassLoaders. Unless you have specified some relationship between the ClassLoaders, classes loaded by one will not be seen by the other. I would try modifying the MemoryClassLoader so that one instance can load both classes.

Upvotes: 4

Related Questions