You can by the way use Javassist to do what I want, but it is a bit of a pain! 
You can write a program that modifies Derived above so that it calls super 
after initializing the field:

  | package examples.vmts.initializationorder.chibaexample;
  | 
  | 
  | import javassist.*;
  | import javassist.bytecode.*;
  | 
  | 
  | public class ModifyDerived {
  |     public static void main( final String[] notUsed ) throws 
NotFoundException, 
  |                                                              BadBytecode, 
  |                                                              
CannotCompileException, 
  |                                                              
java.io.IOException {
  |         final CtClass ctClass = ClassPool.getDefault()
  |                                          .getAndRename( 
"examples.vmts.initializationorder.chibaexample.Derived", 
  |                                                         
"examples.vmts.initializationorder.chibaexample.ModifiedDerived" );
  |         ctClass.replaceClassName( 
  |                 
"examples.vmts.initializationorder.chibaexample.ExternalTest", 
  |                 
"examples.vmts.initializationorder.chibaexample.ModifiedTest" );
  | 
  |         final ClassFile clazz = ctClass.getClassFile();
  |         final MethodInfo constructor = clazz.getMethod( MethodInfo.nameInit 
);
  |         final CodeAttribute code = constructor.getCodeAttribute();
  |         final byte[] bytes = code.getCode();
  |         final CodeIterator codeIter = code.iterator();
  |         codeIter.skipSuperConstructor(); // move to super call, this is 
what skipSuperConstructor does!
  | 
  |         if ( codeIter.hasNext() ) { // need to modify clazz, i.e. super not 
last opcode
  | 
  |             final int superSize = codeIter.next(); // index of opcode after 
super call
  |             final int rest = bytes.length - superSize - 1; // number of 
bytes up to return opcode
  |             final byte[] superCall = new byte[ superSize ];
  |             System.arraycopy( bytes, 0, superCall, 0, superSize );
  |             System.arraycopy( bytes, superSize, bytes, 0, rest );
  |             System.arraycopy( superCall, 0, bytes, rest, superSize );
  |         }
  | 
  |         ctClass.writeFile( "C:\\Personal\\Java\\" );
  |     }
  | }
  | 
The above takes class Derived and modifies it, the new class is similar except 
that:

1. Its name is ModifiedDerived
2. Its field and constructor arguments are of type ModifiedTest
3. And this is the important one, it calls super after it has initialized the 
field

You can test the modified class with:

  | package examples.vmts.initializationorder.chibaexample;
  | 
  | 
  | public class ModifiedTest {
  |     int field = 1;
  | 
  |     Base base() {
  |         return new ModifiedDerived( this );
  |     }
  | 
  |     public static void main( final String[] notUsed ) {
  |         new ModifiedTest().base();
  |     }
  | }
  | 
Which gives the expected result of 1.

As I said at the start all this is a bit of a pain, any chance that the 
Javassist compiler will relax the restriction that super must be first?

Keep up the good work,

Howard.

View the original post : 
http://www.jboss.org/index.html?module=bb&op=viewtopic&p=3882447#3882447

Reply to the post : 
http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=3882447


-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
JBoss-user mailing list
JBoss-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jboss-user

Reply via email to