Re: Problems with Try/Catch Blocks
Andrew Huntwork <[email protected]>
| Newsgroups | gmane.comp.jakarta.bcel.user |
|---|---|
| Message-ID | <[email protected]> |
Posting disassembly for a simple test before and after modification
would be very helpful. There are a couple obvious problems with the
method you've presented: it doesn't replace the NEW instruction that
matches the invokespecial; and it ignores the TargetLostException that
will certainly occur in some code. The second problem is easily
solvable by using InstructionHandle.setInstruction instead of
InstructionList.insert/delete. The first is probably an artifact of not
seeing all your code.
Vincent Marquez wrote:
>
> My problem is, while i'm modifying a method, if the method i'm modifying
> has a try/catch block, I get a "inconsistant stack height" error. It
> seems this only occurs if the Try/Catch block is directly around the
> part i'm modifying. Currently, i'm replacing a constructor from once
> class type to another. It works perfectly except when there are
> Try/Catch blocks. For example, if I have
>
> 1: public static void main( String [] args ) {
> 2: System.out.println( "test" );
> 3: System.out.println( "anotherr test");
> 4: Shape shape = new Shape();
> 5: System.out.println( "final test" );
> 6: }
>
> There isn't a problem if the try/catch is around line 2 and 3. Only if
> it encapsulates line 4, or anything after, will there be the error.
> For legal reasons i'm unable to show all my actual code so I contrived a
> very similar example of our insturmenation method that is below. If
> i'm doing anything wrong/stupid let me know. If you see other problems
> with my code, feel free to let me know also, i'm always looking for ways
> to improve. Thanks for any help/suggestions and MUCH thanks to whoever
> can solve my problem.
>
> --vince
>
> protected void replaceConstructor( ClassGen cg, String original_class,
> String new_class ) {
>
> boolean refresh = false;
> ConstantPoolGen cp_gen = cg.getConstantPool();
> ConstantPool cp = cp_gen.getConstantPool();
> InstructionFactory factory = new InstructionFactory( cg , cp_gen );
>
> Method [] methods = cg.getMethods();
> for ( int x=0; x<methods.length; x++ ) {
> refresh = false;
> MethodGen method_gen = new MethodGen( methods[x],
> cg.getJavaClass().getClassName(), cp_gen );
> Iterator i = method_gen.getInstructionList().iterator();
>
> while ( i.hasNext() ) {
> InstructionHandle handle = ( InstructionHandle )i.next();
>
> if ( handle.getInstruction() instanceof INVOKESPECIAL &&
> ( ( INVOKESPECIAL )handle.getInstruction() ).getClassName( cp_gen
> ).equals( original_class ) && ( ( INVOKESPECIAL )handle.getInstruction()
> ).getMethodName( cp_gen ).equals( "<init>" ) ) {
> try {
> INVOKESPECIAL invk = ( INVOKESPECIAL
> )handle.getInstruction();
>
> method_gen.getInstructionList().insert( invk, factory.createInvoke(
> new_class,
> "name",
> new ObjectType( original_class ),
> invk.getArgumentTypes( cp_gen ),
> Constants.INVOKESTATIC) );
>
> // Delete the old method
> method_gen.getInstructionList().delete( invk );
> refresh = true;
> } catch ( org.apache.bcel.generic.TargetLostException
> e ) {
> Log.write( "Error", + e.toString() );
> }
> }
> }
> if ( refresh ) {
> method_gen.stripAttributes( false );
> method_gen.setMaxStack();
> method_gen.setMaxLocals();
> cg.replaceMethod( methods[x], method_gen.getMethod() );
> }
> }
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>