CannotCompileException / IllegalAccessException with multipl
roger_graham Aug 14, 2006 6:34 AMHello,
I am desperate for help and really hope you can help me. I have two value objects and I want to somehow instrument the code to allow certain methods to be instrumented to write logging into a log file (we are using WSAD and the debugger does not work :-().
If I execute this:
// get (shared) class pool ClassPool pool= ClassPool.getDefault(); // change code for MyTestVO CtClass clazz1 = pool.get("com.test.MyTestVO"); CtMethod method1 = clazz1.getDeclaredMethod("getValue"); method1.insertBefore("System.out.println(\"--- Call to method! ---\");"); pool.toClass( clazz1 ); // invoke method MyTestVO vo = new MyTestVO("Some value"); vo.getValue();
all is fine. However, when I try to execute another modification as this (immediately after):
// change code for MyOtherTestVO CtClass clazz2 = pool.get("com.test.MyOtherTestVO"); CtMethod method2 = clazz2.getDeclaredMethod("getSomeOtherProperty"); method2.insertBefore("System.out.println(\"--- Call to the other method! ---\");"); pool.toClass( clazz2 ); MyOtherTestVO otherVO = new MyOtherTestVO("some other value"); otherVO.getSomeOtherProperty();
I get this stack trace:
--- Call to method! ---
getValue method body
Exception in thread "main" javassist.CannotCompileException: by java.lang.IllegalAccessException: java/lang/ClassLoader
at javassist.ClassPool.toClass(ClassPool.java:834)
at javassist.ClassPool.toClass(ClassPool.java:769)
at com.test.QuickTest.main(QuickTest.java:28)
Caused by: java.lang.IllegalAccessException: java/lang/ClassLoader
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:41)
at java.lang.reflect.Method.invoke(Method.java:386)
at javassist.ClassPool.toClass(ClassPool.java:823)
... 2 more
an anyone please explain what is going on? It is to do with when the CtPool class attempts to reinvoke the findClass via reflection.
Thanks in advance,
Roger
For your info I have included the full sources beneath (but above should be sufficient I think):
com.test.QuickTest
package com.test; import javassist.CannotCompileException; import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod; import javassist.NotFoundException; public class QuickTest { public static void main(String[] args) throws NotFoundException, CannotCompileException { // get (shared) class pool ClassPool pool= ClassPool.getDefault(); // change code for MyTestVO CtClass clazz1 = pool.get("com.test.MyTestVO"); CtMethod method1 = clazz1.getDeclaredMethod("getValue"); method1.insertBefore("System.out.println(\"--- Call to method! ---\");"); pool.toClass( clazz1 ); // invoke method MyTestVO vo = new MyTestVO("Some value"); vo.getValue(); // change code for MyOtherTestVO CtClass clazz2 = pool.get("com.test.MyOtherTestVO"); CtMethod method2 = clazz2.getDeclaredMethod("getSomeOtherProperty"); method2.insertBefore("System.out.println(\"--- Call to the other method! ---\");"); pool.toClass( clazz2 ); MyOtherTestVO otherVO = new MyOtherTestVO("some other value"); otherVO.getSomeOtherProperty(); } }
com.test.MyTestVO
package com.test; public class MyTestVO { private String value; MyTestVO(String value) { this.value = value; } public String getValue() { System.out.println("getValue method body"); return value; } }
com.test.MyOtherTestVO
package com.test; public class MyOtherTestVO { private String someOtherProperty; MyOtherTestVO(String value) { this.someOtherProperty = value; } public String getSomeOtherProperty() { System.out.println("getSomeOtherProperty method body"); return someOtherProperty; } }