-
1. Re: CtMethod.setBody(CtMethod, ClassMap) does not work
chiba Nov 1, 2004 2:02 AM (in response to madman)if I just replace this part of the code, i get a ClassNotFoundException
if I want to load my class after modification.
How did you replace? Could you explain details? -
2. Re: CtMethod.setBody(CtMethod, ClassMap) does not work
madman Nov 2, 2004 4:24 AM (in response to madman)Hello,
in my code I do the following:
CtMethod[] oldMethods = cc.getDeclaredMethods();
CtMethod oldMethod = null;
CtMethod[] newMethods = new CtMethod[oldMethods.length];
//first I insert the new method signatures
for (int i = 0; i < oldMethods.length; i++) {
oldMethod = oldMethods[ i ];
/*I build the new parameters here*/
//...
/*then I define the new Method*/
CtMethod newMethod = new CtMethod(oldMethod.getReturnType(), oldMethod.getName() + "byMe", newParameters, cc);
cc.addMethod(newMethod);
newMethods[ i ] = newMethod;
}
/*then I instrument the method bodies of the old methods*/
/*now I insert the method bodies of the new methods*/
CtMethod nMethod = null;
for (int i = 0; i < newMethods.length; i++) {
nMethod = cc.getDeclaredMethod(newMethods[ i ].getName());
/* and here is difference: first the fine working version:*/
/* The helper method buildParameterString just reads the parameters
from the new method and gives the correct parameters to
the old method. This must be done because the new method
has more parameters.*/
nMethod.setBody("return " + oldMethods[ i ].getName() + "(" + buildParameterString(oldMethods[ i ].getParameterTypes().length) + ");}");
/*if I replace the above mentioned line with the second version, I get
a ClassNotFoundException:*/
nMethod.setBody(cc.getDeclaredMethod(oldMethods[ i ].getName()), null);
cc.setModifiers(cc.getModifiers() & ~Modifier.ABSTRACT);
}
//end of code
I also tried to copy directly in the first for(...), but it was the same result.
I looked at the resulting files with javap, and the modifications are also done
in the second case. The method bodies are copied. But I can't load them.
If you need more information, just ask.
Great thanks that you try to help me. -
3. Re: CtMethod.setBody(CtMethod, ClassMap) does not work
chiba Nov 2, 2004 10:08 AM (in response to madman)/* if I replace the above mentioned line with the second version, I get a ClassNotFoundException:*/ nMethod.setBody(cc.getDeclaredMethod(oldMethods[ i ].getName()), null); cc.setModifiers(cc.getModifiers() & ~Modifier.ABSTRACT);
So you received a ClassNotFoundException when you loaded this
modified class. How did you load that class? By a user-defined class
loader or anything else?
I also want to know what class was not found. The modified class?
Another class that the modified class refers to? -
4. Re: CtMethod.setBody(CtMethod, ClassMap) does not work
madman Nov 2, 2004 1:01 PM (in response to madman)Hi,
I use the normal URLClassLoader in java 1.4.2. In my opinion the URL must be
correct as I can load it when I use version 1 with the indirection.
The class not found is the modified one.
Other classes in the same directory, for example the interface of the
modified class, which was also modified, are found. I know this because
I tried to load them seperately in another URLClassLoader with the same
URL.
I hope this helps.
Thanks a lot. -
5. Re: CtMethod.setBody(CtMethod, ClassMap) does not work
chiba Nov 2, 2004 11:08 PM (in response to madman)One possibility is that URLClassLoader could find
the modified class file but failed bytecode verification.
(I'm not sure, though.)
Can you make sure that you can load the modified
class without a URL class loader (with a system
class loader)? If you cannot, that means the modified
class file is broken for some reason.
The modified class file might include two methods with
the same name and signature.nMethod.setBody(cc.getDeclaredMethod(oldMethods[ i ].getName()), null);
Do you know getDeclaredMethod() randomly chooses
one of the methods with the given name if there are
multiple methods with the same name but a different
signature?
I think the code above should be:nMethod.setBody(oldMethods[ i ], null)
Hope it helps. -
6. Re: CtMethod.setBody(CtMethod, ClassMap) does not work
madman Nov 3, 2004 3:50 AM (in response to madman)Result is the same with the system classloader. Maybe the classfile is
really broken. But why?
I`m sure there are no methods with the same name as I tested
it with a class with one method. And the methods added by me have
more parameters and the name is "oldName" + "byMe".
I also tried setBody(oldMethods[ i ], null), but it was the same result
again. I also tried to copy the method body before instrumenting the
methods (in this case I then have to instrument all bodies), but again I
got a ClassNotFoundException.
Thanks for your help, I`m really thankful. -
7. Re: CtMethod.setBody(CtMethod, ClassMap) does not work
chiba Nov 3, 2004 9:53 AM (in response to madman)Did the system class loader throw ClassNotFoundException?
If the class file is broken, it should throw VerifyError. -
8. Re: CtMethod.setBody(CtMethod, ClassMap) does not work
madman Nov 4, 2004 11:04 AM (in response to madman)Hallo,
I tried it with the SystemClassLoader again and you were right. It's
no ClassNotFoundException, it throws a java.lang.ClassFormatError.
Sorry for writing something different here.
I hope that helps. -
9. Re: CtMethod.setBody(CtMethod, ClassMap) does not work
chiba Nov 4, 2004 11:28 AM (in response to madman)OK, good. What was the detailed message
of that ClassFormatError? No message
except the exception type name? -
10. Re: CtMethod.setBody(CtMethod, ClassMap) does not work
madman Nov 4, 2004 11:50 AM (in response to madman)Ok, I'll post the whole StackTrace here:
Exception in thread "main" java.lang.ClassFormatError: test/AskMe (Arguments can't fit into locals)
at java.lang.ClassLoader.defineClass0(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:537)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:123)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:251)
at java.net.URLClassLoader.access$100(URLClassLoader.java:55)
at java.net.URLClassLoader$1.run(URLClassLoader.java:194)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:187)
at java.lang.ClassLoader.loadClass(ClassLoader.java:289)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:274)
at java.lang.ClassLoader.loadClass(ClassLoader.java:235)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:302)
at java.lang.ClassLoader.defineClass0(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:537)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:123)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:251)
at java.net.URLClassLoader.access$100(URLClassLoader.java:55)
at java.net.URLClassLoader$1.run(URLClassLoader.java:194)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:187)
at java.lang.ClassLoader.loadClass(ClassLoader.java:289)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:274)
at java.lang.ClassLoader.loadClass(ClassLoader.java:235)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:302)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:141)
at testIt.main(testIt.java:8)
I use the command ClassLoader.getSystemClassLoader().loadClass("test.AskMe");
to load the class. I think, that should be correct so far. If it isn't, please write it and I'll try it again, of course.
Thanks for that real quick reply. -
11. Re: CtMethod.setBody(CtMethod, ClassMap) does not work
chiba Nov 4, 2004 11:16 PM (in response to madman)Exception in thread "main" java.lang.ClassFormatError: test/AskMe (Arguments can't fit into locals)
I see. Unfortunately, the argument to CtMethod#setBody() must
be a method that has the exactly same signature. The reason of
your problem is that the number of arguments were different
between the original method and the new method.
Javassist has not supported yet the function for increasing the number
of parameters of an existing method. :< -
12. Re: CtMethod.setBody(CtMethod, ClassMap) does not work
madman Nov 5, 2004 3:53 AM (in response to madman)Ok, I think must go on with the indirection, then.
Great thanks for all you postings and your help.