[
http://jira.jboss.com/jira/browse/JASSIST-53?page=comments#action_12403643 ]
Yanic Inghelbrecht commented on JASSIST-53:
-------------------------------------------
Doh!
You're absolutely right of course.
The error I got in my real code was a but different, namely
java.lang.VerifyError: (class: test_exception_handling/class_method_call/Test, method:
<init> signature: ()V) Register 0 contains wrong type
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
at java.lang.Class.privateGetPublicMethods(Unknown Source)
at java.lang.Class.getMethods(Unknown Source)
at com.tracemodeler.trace.TraceRunnerForJUnit.init(TraceRunnerForJUnit.java:124)
at com.tracemodeler.trace.TraceRunnerForJUnit.<init>(TraceRunnerForJUnit.java:65)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.junit.internal.requests.ClassRequest.buildRunner(ClassRequest.java:33)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:28)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:26)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:24)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:40)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:30)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:445)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
I did try to reduce it to the example given above, but then the error message changed. But
both only occur when I try to instrument a super-constructor call.
Anyway, I'll wait for the fix of jassist-52 and retry my code. I'll also
never-ever-ever again try to catch an exception thrown by the super constructor ;o)
I'll add another comment to this one to let you know how it went, once 52 is done.
Thanks.
Best regards,
Yanic
VerifyError (constructor must call super() or this()) through
ConstructorCall#replace when block includes a try/catch block
---------------------------------------------------------------------------------------------------------------------------
Key: JASSIST-53
URL:
http://jira.jboss.com/jira/browse/JASSIST-53
Project: Javassist
Issue Type: Bug
Environment: javassist 3.7.1 (from cvs HEAD), jdk 1.6.0_03 on winXP
Reporter: Yanic Inghelbrecht
Assigned To: Shigeru Chiba
Included is the simplest test case I could find that reproduces the error, it consists of
two classes : Client (to be instrumented) and Main (does the instrumentation).
When run, it produces the following exception trace :
Exception in thread "main" java.lang.VerifyError: (class:
test_verify_error_with_try_catch_in_replace_for_constructor_call/Client, method:
<init> signature: ()V) Constructor must call super() or this()
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Unknown Source)
at java.lang.Class.getConstructor0(Unknown Source)
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at
test_verify_error_with_try_catch_in_replace_for_constructor_call.Main.main(Main.java:31)
Also, when the replacement block uses $0 (the constructed object), for example :
String block = "{try {$_=$proceed($$);} catch (Throwable t)
{System.out.println($0);}}";
the error message changes to :
Exception in thread "main" java.lang.VerifyError: (class:
test_verify_error_with_try_catch_in_replace_for_constructor_call/Client, method:
<init> signature: ()V) Register 1 contains wrong type
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Unknown Source)
at java.lang.Class.getConstructor0(Unknown Source)
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at
test_verify_error_with_try_catch_in_replace_for_constructor_call.Main.main(Main.java:31)
Again, this is related (for me at least) to JIRA JAVASSIST 51 and 52, since those also
deal with adding a try/catch block using replace in an ExprEditor#edit method.
So far I've reported three issues all related to adding try/catch block with a
replace in ExprEditor#edit :
51 for NewExpr
52 for MethodCall
53 for ConstructorCall
I don't use the other ExprEditor#edit methods (i.e. edit(Handler), edit(FieldAccess),
...), so I don't expect to report any similar issues. However, you may want to check
them to see if they suffer from the same problem.
I hope it's an easy fix for you!
Best regards,
Yanic
-- source for Client.java
package test_verify_error_with_try_catch_in_replace_for_constructor_call;
public class Client {
//
}
-- source for Main.java
package test_verify_error_with_try_catch_in_replace_for_constructor_call;
import java.lang.reflect.Method;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtBehavior;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.Loader;
import javassist.NotFoundException;
import javassist.Translator;
import javassist.expr.ConstructorCall;
import javassist.expr.ExprEditor;
public class Main {
public static void main(String[] args) throws Exception {
ClassPool pool = new ClassPool(true);
Loader cl = new Loader();
try {
cl.addTranslator(pool, new MyTranslator());
} catch (Exception e) {
e.printStackTrace();
return;
}
// load the Client class
Class
clientClass=cl.loadClass("test_verify_error_with_try_catch_in_replace_for_constructor_call.Client");
// create an instance
Object client=clientClass.newInstance();
}
static public class MyTranslator extends ExprEditor implements Translator {
public void onLoad(ClassPool pool, String classname) throws NotFoundException,
CannotCompileException {
CtClass cc = pool.get(classname);
modify(cc);
}
public void modify(CtClass c) throws CannotCompileException {
for (CtBehavior b : c.getDeclaredBehaviors()) {
b.instrument(this);
}
}
@Override
public void edit(ConstructorCall cc) throws CannotCompileException {
// simple proceed surrounded by a try/catch block
// each block gives a different VerifyError
String block = "{try {$_=$proceed($$);} catch (Throwable t) {}}";
// String block = "{try {$_=$proceed($$);} catch (Throwable t)
{System.out.println($0);}}";
cc.replace(block);
}
public void start(ClassPool pool) throws NotFoundException, CannotCompileException {
// do nothing
}
}
}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://jira.jboss.com/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira