shyam334 / objenesis

Automatically exported from code.google.com/p/objenesis
0 stars 0 forks source link

another possible and portable way to instantiate a class #20

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
If the original class is not final you can create a class that extends it, 
creating direct JVM byte-code, and loading the created class. Then creating an 
instance of the extended class will invoke the constructor of the extending 
class, but since the JVM code is generated calling the superconstructor can be 
skipped (simply not generating the code into the constructor that invokes 
super).

You may perhaps even create the extending class if the original class is final 
accessing the original class object already loaded and altering the "final" 
modifier using reflection.

Original issue reported on code.google.com by peter.ve...@gmail.com on 16 Aug 2013 at 8:01

GoogleCodeExporter commented 9 years ago
Hi, that sounds interesting. Would be able to provide a patch containing this 
instantiator?

Original comment by henri.tr...@gmail.com on 6 Oct 2013 at 10:55

GoogleCodeExporter commented 9 years ago
No unfoirtunately I am not, having no time to devote to that.

If you look at the disassembly of a class file, for example:

  public javax0.casuar.Node(java.lang.String);
    flags: ACC_PUBLIC
    Code:
      stack=4, locals=3, args_size=2
         0: aload_0       
         1: invokespecial #75                 // Method java/lang/Object."<init>":()V
         4: aload_0       
         5: aconst_null   
         6: putfield      #59                 // Field file:Ljava/io/File;
         9: aload_0       
        10: aconst_null   
        11: putfield      #36                 // Field subdirs:[Ljava/io/File;
        14: aload_0       
        15: aconst_null   
        16: putfield      #42                 // Field children:[Ljavax0/casuar/Node;
        19: aload_1       
        20: ifnonnull     32
        23: ldc           #76                 // String user.home
        25: invokestatic  #78                 // Method java/lang/System.getProperty:(Ljava/lang/String;)Ljava/lang/String;
        28: astore_2      
        29: goto          34
        32: aload_1       
        33: astore_2      
        34: aload_0       
        35: new           #45                 // class java/io/File
        38: dup           
        39: aload_2       
        40: invokespecial #84                 // Method java/io/File."<init>":(Ljava/lang/String;)V
        43: putfield      #59                 // Field file:Ljava/io/File;
        46: new           #85                 // class javax0/casuar/Node$SubdirCollector
        49: dup           
        50: aload_0       
        51: dup           
        52: invokevirtual #87                 // Method java/lang/Object.getClass:()Ljava/lang/Class;
        55: pop           
        56: aconst_null   
        57: invokespecial #91                 // Method javax0/casuar/Node$SubdirCollector."<init>":(Ljavax0/casuar/Node;Ljavax0/casuar/Node$SubdirCollector;)V
        60: invokevirtual #94                 // Method javax0/casuar/Node$SubdirCollector.start:()V
        63: return        

You can see that the invocatio of the super() is explicitly coded into the file 
as 

         0: aload_0       
         1: invokespecial #75                 // Method java/lang/Object."<init>":()V

If you create the JVM code using asm tools, like cglib does then you can skip 
this.

Original comment by peter.ve...@gmail.com on 6 Oct 2013 at 11:47

GoogleCodeExporter commented 9 years ago
Wouldn't the JVM's bytecode verifier reject the class?

Original comment by nat.pr...@gmail.com on 6 Oct 2013 at 11:52

GoogleCodeExporter commented 9 years ago
One should give a try. My bet is that it will not.

Original comment by peter.ve...@gmail.com on 6 Oct 2013 at 11:55

GoogleCodeExporter commented 9 years ago
Have you tried?

I would be surprised if the bytecode verifier did not reject the class when the 
classloader defined the class from the invalid bytecode.

Original comment by nat.pr...@gmail.com on 6 Oct 2013 at 12:15