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 "Hiller, Dean D (Dean)" <dh...@avaya.com> on 2005/01/26 20:12:32 UTC

how to get the type info from this small code snippet?

 

package mod.fieldrefdepend;
import mod.dummy.DummyClass;
public class ClassDependsOnReferenceInFieldDeclaration {
            private Class c = DummyClass.class; 
}

Anyone know how to process the ConstantPool or the instruction code to
find out DummyClass.class is used in this context(ie. Class c =
DummyClass.class).  I don't care about other contexts.

Thanks,

dean

Here is the constant pool and byte code from my logs that I print out

   class=mod.fieldrefdepend.ClassDependsOnReferenceInFieldDeclaration
 
const[1]=java.lang.Class.forName(Ljava/lang/String;)Ljava/lang/Class;
inst=org.apache.bcel.classfile.ConstantMethodref
      const[2]=java.lang.ClassNotFoundException
inst=org.apache.bcel.classfile.ConstantClass
      const[3]=java.lang.NoClassDefFoundError
inst=org.apache.bcel.classfile.ConstantClass
      const[4]=java.lang.ClassNotFoundException.getMessage
()Ljava/lang/String; inst=org.apache.bcel.classfile.ConstantMethodref
      const[5]=java.lang.NoClassDefFoundError.<init>
(Ljava/lang/String;)V inst=org.apache.bcel.classfile.ConstantMethodref
      const[6]=java.lang.Object.<init> ()V
inst=org.apache.bcel.classfile.ConstantMethodref
 
const[7]=mod.fieldrefdepend.ClassDependsOnReferenceInFieldDeclaration.cl
ass$mod$dummy$DummyClass Ljava/lang/Class; 
      const[8]="mod.dummy.DummyClass"
inst=org.apache.bcel.classfile.ConstantString
 
const[9]=mod.fieldrefdepend.ClassDependsOnReferenceInFieldDeclaration.cl
ass$ (Ljava/lang/String;)Ljava/lang/Class; 
 
const[10]=mod.fieldrefdepend.ClassDependsOnReferenceInFieldDeclaration.c
Ljava/lang/Class; inst=org.apache.bcel.classfile.ConstantFieldref
 
const[11]=mod.fieldrefdepend.ClassDependsOnReferenceInFieldDeclaration
inst=org.apache.bcel.classfile.ConstantClass
      const[12]=java.lang.Object
inst=org.apache.bcel.classfile.ConstantClass
      const[13]=c inst=org.apache.bcel.classfile.ConstantUtf8
      const[14]=Ljava/lang/Class;
inst=org.apache.bcel.classfile.ConstantUtf8
      const[15]=class$mod$dummy$DummyClass
inst=org.apache.bcel.classfile.ConstantUtf8
      const[16]=Synthetic inst=org.apache.bcel.classfile.ConstantUtf8
      const[17]=<init> inst=org.apache.bcel.classfile.ConstantUtf8
      const[18]=()V inst=org.apache.bcel.classfile.ConstantUtf8
      const[19]=Code inst=org.apache.bcel.classfile.ConstantUtf8
      const[20]=LineNumberTable
inst=org.apache.bcel.classfile.ConstantUtf8
      const[21]=LocalVariableTable
inst=org.apache.bcel.classfile.ConstantUtf8
      const[22]=this inst=org.apache.bcel.classfile.ConstantUtf8
 
const[23]=Lmod/fieldrefdepend/ClassDependsOnReferenceInFieldDeclaration;
inst=org.apache.bcel.classfile.ConstantUtf8
      const[24]=class$ inst=org.apache.bcel.classfile.ConstantUtf8
      const[25]=(Ljava/lang/String;)Ljava/lang/Class;
inst=org.apache.bcel.classfile.ConstantUtf8
      const[26]=x1 inst=org.apache.bcel.classfile.ConstantUtf8
      const[27]=Ljava/lang/ClassNotFoundException;
inst=org.apache.bcel.classfile.ConstantUtf8
      const[28]=x0 inst=org.apache.bcel.classfile.ConstantUtf8
      const[29]=Ljava/lang/String;
inst=org.apache.bcel.classfile.ConstantUtf8
      const[30]=SourceFile inst=org.apache.bcel.classfile.ConstantUtf8
      const[31]=ClassDependsOnReferenceInFieldDeclaration.java
inst=org.apache.bcel.classfile.ConstantUtf8
      const[32]=java.lang.Class
inst=org.apache.bcel.classfile.ConstantClass
      const[33]=forName (Ljava/lang/String;)Ljava/lang/Class;
inst=org.apache.bcel.classfile.ConstantNameAndType
      const[34]=java/lang/ClassNotFoundException
inst=org.apache.bcel.classfile.ConstantUtf8
      const[35]=java/lang/NoClassDefFoundError
inst=org.apache.bcel.classfile.ConstantUtf8
      const[36]=getMessage ()Ljava/lang/String;
inst=org.apache.bcel.classfile.ConstantNameAndType
      const[37]=<init> (Ljava/lang/String;)V
inst=org.apache.bcel.classfile.ConstantNameAndType
      const[38]=<init> ()V
inst=org.apache.bcel.classfile.ConstantNameAndType
      const[39]=class$mod$dummy$DummyClass Ljava/lang/Class;
inst=org.apache.bcel.classfile.ConstantNameAndType
      const[40]=mod.dummy.DummyClass
inst=org.apache.bcel.classfile.ConstantUtf8
      const[41]=class$ (Ljava/lang/String;)Ljava/lang/Class;
inst=org.apache.bcel.classfile.ConstantNameAndType
      const[42]=c Ljava/lang/Class;
inst=org.apache.bcel.classfile.ConstantNameAndType
 
const[43]=mod/fieldrefdepend/ClassDependsOnReferenceInFieldDeclaration
inst=org.apache.bcel.classfile.ConstantUtf8
      const[44]=java/lang/Object
inst=org.apache.bcel.classfile.ConstantUtf8
      const[45]=java/lang/Class
inst=org.apache.bcel.classfile.ConstantUtf8
      const[46]=forName inst=org.apache.bcel.classfile.ConstantUtf8
      const[47]=getMessage inst=org.apache.bcel.classfile.ConstantUtf8
      const[48]=()Ljava/lang/String;
inst=org.apache.bcel.classfile.ConstantUtf8
      const[49]=(Ljava/lang/String;)V
inst=org.apache.bcel.classfile.ConstantUtf8


      method=<init>
         method ret type=void
         instr=aload_0[42](1)
         instr=invokespecial[183](3) 6
         instr=aload_0[42](1)
         instr=getstatic[178](3) 7
         instr=ifnonnull[199](3) -> getstatic 7
         instr=ldc[18](2) 8
         instr=invokestatic[184](3) 9
         instr=dup[89](1)
         instr=putstatic[179](3) 7
         instr=goto[167](3) -> putfield 10
         instr=getstatic[178](3) 7
         instr=putfield[181](3) 10
         instr=return[177](1)
      method=class$
         method ret type=Class
         method param[0]=String
         instr=aload_0[42](1)
         instr=invokestatic[184](3) 1
         instr=areturn[176](1)
         instr=astore_1[76](1)
         instr=new[187](3) 3
         instr=dup[89](1)
         instr=aload_1[43](1)
         instr=invokevirtual[182](3) 4
         instr=invokespecial[183](3) 5
         instr=athrow[191](1)


Re: how to get the type info from this small code snippet?

Posted by David Hovemeyer <da...@cs.umd.edu>.
On Wed, Jan 26, 2005 at 12:12:32PM -0700, Hiller, Dean D (Dean) wrote:
>  
> 
> package mod.fieldrefdepend;
> import mod.dummy.DummyClass;
> public class ClassDependsOnReferenceInFieldDeclaration {
>             private Class c = DummyClass.class; 
> }
> 
> Anyone know how to process the ConstantPool or the instruction code to
> find out DummyClass.class is used in this context(ie. Class c =
> DummyClass.class).  I don't care about other contexts.

If the code was generated by javac from JDK 1.5, just look
for a LDC instruction that refers to a Constant_Class.

I believe that for javac from JDK 1.4 and earlier, SomeClass.class
expressions are compiled to

 - check a synthetic static field which caches the Class
   object

 - if the field contains null, call a synthetic static method
   (called "class$", judging from the code you posted),
   passing the name of the class as a param.  The return value
   of this method is the Class object.

So, I think you can find out what classes are involved in
SomeClass.class expressions by scanning method bytecode for sequences of

  LDC "com.foobar.SomeClass"
  INVOKESTATIC "java.lang.Class class$(java.lang.String)"

You will probably want to use ConstantPoolGen/ClassGen/MethodGen
to produce an InstructionList for each method, unless you want
to write code to disassemble the actual bytecodes.  As a side
benefit, these classes make it easier to extract constants from
the constant pool (e.g., symbolic information for particular
instructions).

Other compilers (e.g., jikes, Eclipse) may generate different
bytecode.

Hope that helps,

-Dave

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