You are viewing a plain text version of this content. The canonical link for it is here.
Posted to bcel-user@jakarta.apache.org by Raghu L <ra...@gmail.com> on 2005/05/02 13:53:28 UTC

Probelm in instrumenting Junit test classes

Hi,

I am getting verification problem after instrumenting Junit test
classes. Here is the procedure I used

private Method instrumentMethod(Method m) 
{

    Code   code1 = m.getCode();
    MethodGen           mg  = new MethodGen(m, className, cp);
    InstructionList     il  = mg.getInstructionList();
    InstructionHandle[] ihs = il.getInstructionHandles();
    methodName=m.getName();

	if(! (methodName.indexOf("test")>=0) ) return mg.getMethod();
	
	InstructionList code = new InstructionList();

	InstructionFactory factory = new InstructionFactory(cp);


	code.append(new PUSH(cp,methodName));	
	code.append(new PUSH(cp,"Raghu"));
	code.append(new PUSH(cp,"JUnit"));
	code.append(new PUSH(cp,className));
	code.append(factory.createInvoke("invokeClassName",
				    "invokeMethodName",Type.VOID,new Type[] {
Type.STRING,Type.STRING,Type.STRING,Type.STRING
},Constants.INVOKESTATIC));
	il.insert(ihs[0],code);
	il.setPositions();

return mg.getMethod();

}

After instrumention am getting this verification error:

VERIFIED_REJECTED
Instruction invokestatic[184](3) 51 constraint violated: Referenced
method 'assertTrue' with expected signature not found in class
'MatrixTest'. The native verifier possibly allows the method to be
declared in some superclass or implemented interface, which the Java
Virtual Machine Specification, Second Edition does not.

VERIFIED_NOTYET
Not yet verified.

Instrumentation procedure seems to working with other classes except
JUnit testcase classes.

Runtime Error:
Exception in thread "main" java.lang.VerifyError: (class: MatrixTest,
method: suite signature: ()Ljunit/framework/Test;) Illegal constant
pool index

Snapshot of bytecode for instrumented class:

public static junit.framework.Test suite();
  Code:
   0:	new	#38; //class junit/framework/TestSuite
   3:	dup
   4:	ldc_w	#10167; //BOGUS_TAG:100 <Incorrect CP index:10167>
   7:	nop
   8:	dload_2
   9:	areturn

Instrumentation class and bytecode attached.

Thanx.

Re: Probelm in instrumenting Junit test classes

Posted by Andrew Huntwork <as...@huntwork.net>.
it looks like everything is fine except that i think you need to do some 
constant pool BS.  i think it's 
cg.setconstantpool(cp.getfinalconstantpool) or something like that. 
that's from a very fuzzy memory of long ago.  sandmark takes care of 
these annoying repetitive details, so i tend to forget them.  see 
apidocs for details.

the bcel verifier error is basically bogus.  it's very likely that if 
you verify the original class, it will produce the same error.

also, your test for deciding if you want to instrument a method is 
slightly bogus.  you probably want !methodName.startWith("test") or 
maybe methodName.indexOf("test") != 0.  but i think you probably already 
know that or would have figured it out real soon now with your testing.

Raghu L wrote:
> Hi,
> 
> I am getting verification problem after instrumenting Junit test
> classes. Here is the procedure I used
> 
> private Method instrumentMethod(Method m) 
> {
> 
>     Code   code1 = m.getCode();
>     MethodGen           mg  = new MethodGen(m, className, cp);
>     InstructionList     il  = mg.getInstructionList();
>     InstructionHandle[] ihs = il.getInstructionHandles();
>     methodName=m.getName();
> 
> 	if(! (methodName.indexOf("test")>=0) ) return mg.getMethod();
> 	
> 	InstructionList code = new InstructionList();
> 
> 	InstructionFactory factory = new InstructionFactory(cp);
> 
> 
> 	code.append(new PUSH(cp,methodName));	
> 	code.append(new PUSH(cp,"Raghu"));
> 	code.append(new PUSH(cp,"JUnit"));
> 	code.append(new PUSH(cp,className));
> 	code.append(factory.createInvoke("invokeClassName",
> 				    "invokeMethodName",Type.VOID,new Type[] {
> Type.STRING,Type.STRING,Type.STRING,Type.STRING
> },Constants.INVOKESTATIC));
> 	il.insert(ihs[0],code);
> 	il.setPositions();
> 
> return mg.getMethod();
> 
> }
> 
> After instrumention am getting this verification error:
> 
> VERIFIED_REJECTED
> Instruction invokestatic[184](3) 51 constraint violated: Referenced
> method 'assertTrue' with expected signature not found in class
> 'MatrixTest'. The native verifier possibly allows the method to be
> declared in some superclass or implemented interface, which the Java
> Virtual Machine Specification, Second Edition does not.
> 
> VERIFIED_NOTYET
> Not yet verified.
> 
> Instrumentation procedure seems to working with other classes except
> JUnit testcase classes.
> 
> Runtime Error:
> Exception in thread "main" java.lang.VerifyError: (class: MatrixTest,
> method: suite signature: ()Ljunit/framework/Test;) Illegal constant
> pool index
> 
> Snapshot of bytecode for instrumented class:
> 
> public static junit.framework.Test suite();
>   Code:
>    0:	new	#38; //class junit/framework/TestSuite
>    3:	dup
>    4:	ldc_w	#10167; //BOGUS_TAG:100 <Incorrect CP index:10167>
>    7:	nop
>    8:	dload_2
>    9:	areturn
> 
> Instrumentation class and bytecode attached.
> 
> Thanx.
> 
> 
> ------------------------------------------------------------------------
> 
> import java.util.*;
> import org.apache.bcel.*;
> import org.apache.bcel.classfile.*;
> import org.apache.bcel.generic.*;
> import org.apache.bcel.Constants;
> import org.apache.bcel.verifier.structurals.Frame;
> import org.apache.bcel.verifier.*;
> 
> import java.io.*;
> 
> public class JunitInstrument implements Constants
> {
>   private	static 	String          	className,methodName;
>   private	static 	ConstantPoolGen		cp;
>   JavaClass     				java_class;
>   ConstantPool  				constants;  
>   public static int mProbe;
> 
>   public JunitInstrument()
>   {
> 
>   }
> 
> private void addMethodReference()
> 	{
> 
> 	mProbe = cp.addMethodref("invokeClassName",
> 				    "invokeMathodName",
> 				    "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
> 
> 	}
> 
> private Method instrumentMethod(Method m) 
> {
> 
>     Code   code1 = m.getCode();
>     MethodGen           mg  = new MethodGen(m, className, cp);
>     InstructionList     il  = mg.getInstructionList();
>     InstructionHandle[] ihs = il.getInstructionHandles();
>     methodName=m.getName();
> 
> 	if(! (methodName.indexOf("test")>=0)  ) return mg.getMethod();
> 	
> 	InstructionList code = new InstructionList();
> 
> 	InstructionFactory factory = new InstructionFactory(cp);
> 
> 
> 	code.append(new PUSH(cp,methodName));	
> 	code.append(new PUSH(cp,"Raghu"));
> 	code.append(new PUSH(cp,"JUnit"));
> 	code.append(new PUSH(cp,className));
> 	code.append(factory.createInvoke("invokeClassName",
> 				    "invokeMethodName",Type.VOID,new Type[] { Type.STRING,Type.STRING,Type.STRING,Type.STRING },Constants.INVOKESTATIC));
> 
> 	il.insert(ihs[0],code);
> 	il.setPositions();
> 	mg.setMaxStack(code1.getMaxStack()+4);
> 
> return mg.getMethod();
> 
> }
> 
> public ConstantPoolGen instrument(JavaClass java_class)
> {
> 
> try{
> 
> constants  = java_class.getConstantPool();
> cp = new ConstantPoolGen(constants);
> //addMethodReference();
> 
> className=java_class.getClassName();
> Method[] methods = java_class.getMethods();
> 
> for(int j=0; j < methods.length; j++)
> 	methods[j] = instrumentMethod(methods[j]);
> 
> return cp;
> }catch(Exception e)
> {
> e.printStackTrace();
> return cp;
> }
> 
> 
> }
> 
>   public static void main(String[] argv) { 
> 	
> try{
> for(int i=0;i<argv.length;i++){
>   JunitInstrument inst=new JunitInstrument();	
>   JavaClass  java_class = new ClassParser(argv[i]).parse();
>   Method[] methods = java_class.getMethods();	  
>   cp=inst.instrument(java_class);
>   java_class.setConstantPool(cp.getFinalConstantPool());
>   java_class.dump(argv[i]);
> 
>   verif(argv[i],methods.length-1);
> 
> 	}
> 
> }catch(Exception e){e.printStackTrace();}
> 
>   }
> 
>  private static void verif(String classname,int n)
>   {
>  	try{
> 	  JavaClass	java_class = new ClassParser(classname).parse();
> 	  Verifier v=VerifierFactory.getVerifier(java_class.getClassName());
> 	  System.out.println(v.doPass1());
> 	  System.out.println(v.doPass2());
>   	  System.out.println(v.doPass3a(n));
> 	  System.out.println(v.doPass3b(n));
>   	  }catch(Exception e) {
>       			e.printStackTrace();
>     		}
>   }
> 
> 
>   public void instrument(String claz) { 
> 
> 	try{	
> 		JavaClass  java_class = new ClassParser(claz).parse();
> 		Method[] methods = java_class.getMethods();	  
> 		cp=instrument(java_class);
> 		java_class.setConstantPool(cp.getFinalConstantPool());
> 		java_class.dump(claz);
> 
>     	} catch(Exception e) {
>       		e.printStackTrace();
>     	}
> 
>   }
> 
> }
> 
> 
> ------------------------------------------------------------------------
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: bcel-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: bcel-dev-help@jakarta.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: bcel-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: bcel-dev-help@jakarta.apache.org