[jboss-jira] [JBoss JIRA] Created: (JASSIST-53) VerifyError (constructor must call super() or this()) through ConstructorCall#replace when block includes a try/catch block

Yanic Inghelbrecht (JIRA) jira-events at lists.jboss.org
Thu Mar 13 07:13:58 EDT 2008


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

        



More information about the jboss-jira mailing list