Class ClassFile


  • public class ClassFile
    extends java.lang.Object
    An object that represents the Java™ "class file" format.

    ClassFile(InputStream) creates a ClassFile object from the bytecode read from the given InputStream.

    store(OutputStream) generates Java™ bytecode which is suitable for being processed by a Java™ virtual machine.

    • Constructor Detail

      • ClassFile

        public ClassFile​(short accessFlags,
                         java.lang.String thisClassFd,
                         java.lang.String superclassFd,
                         java.lang.String[] interfaceFds)
        Construct from parsed components.
        Parameters:
        accessFlags - as defined by Mod
        thisClassFd - the field descriptor for this class
        superclassFd - the field descriptor for the extended class (e.g. "Ljava/lang/Object;")
        interfaceFds - the field descriptors for the implemented interfaces
      • ClassFile

        public ClassFile​(java.io.InputStream inputStream)
                  throws java.io.IOException
        Read "class file" data from a InputStream and construct a ClassFile object from it.

        If the ClassFile is created with this constructor, then most modifying operations lead to a UnsupportedOperationException; only fields, methods and attributes can be added.

        Throws:
        java.io.IOException
    • Method Detail

      • addSourceFileAttribute

        public void addSourceFileAttribute​(java.lang.String sourceFileName)
        Adds a "SourceFile" attribute to this class file. (Does not check whether one exists already.)
        Parameters:
        sourceFileName -
      • addDeprecatedAttribute

        public void addDeprecatedAttribute()
        Adds the "Deprecated" attribute to this class.
      • getInnerClassesAttribute

        public ClassFile.InnerClassesAttribute getInnerClassesAttribute()
        Find the "InnerClasses" attribute of this class file
        Returns:
        null if this class has no "InnerClasses" attribute
      • addInnerClassesAttributeEntry

        public void addInnerClassesAttributeEntry​(ClassFile.InnerClassesAttribute.Entry e)
        Create an "InnerClasses" attribute if it does not exist, then add the given entry to the "InnerClasses" attribute.
        Parameters:
        e -
      • getThisClassName

        public java.lang.String getThisClassName()
        Returns:
        The fully qualified name of this class, e.g. "pkg1.pkg2.Outer$Inner"
      • setVersion

        public void setVersion​(short majorVersion,
                               short minorVersion)
        Sets the major and minor class file version numbers (JVMS 4.1). The class file version defaults to the JDK 1.1 values (45.3) which execute on virtually every JVM.
      • getMajorVersion

        public short getMajorVersion()
        Returns:
        The current major class file version number
      • getMinorVersion

        public short getMinorVersion()
        Returns:
        The current minor class file version number
      • addConstantClassInfo

        public short addConstantClassInfo​(java.lang.String typeFd)
        Return the constant index number for a "CONSTANT_Class_info" structure to the class file. If the class hasn't been added before, add it to the constant pool. Otherwise return the constant number for that element of the pool.
        See Also:
        JVM specification, section 4.4.1
      • addConstantFieldrefInfo

        public short addConstantFieldrefInfo​(java.lang.String classFd,
                                             java.lang.String fieldName,
                                             java.lang.String fieldFd)
        Add a "CONSTANT_Fieldref_info" structure to the class file.
        See Also:
        JVM specification, section 4.4.2
      • addConstantMethodrefInfo

        public short addConstantMethodrefInfo​(java.lang.String classFd,
                                              java.lang.String methodName,
                                              java.lang.String methodMd)
        Add a "CONSTANT_Methodref_info" structure to the class file.
        See Also:
        JVM specification, section 4.4.2
      • addConstantInterfaceMethodrefInfo

        public short addConstantInterfaceMethodrefInfo​(java.lang.String classFd,
                                                       java.lang.String methodName,
                                                       java.lang.String methodMd)
        Add a "CONSTANT_InterfaceMethodref_info" structure to the class file.
        See Also:
        JVM specification, section 4.4.2
      • addConstantStringInfo

        public short addConstantStringInfo​(java.lang.String string)
        Add a "CONSTANT_String_info" structure to the class file.
        See Also:
        JVM specification, section 4.4.3
      • addConstantIntegerInfo

        public short addConstantIntegerInfo​(int value)
        Add a "CONSTANT_Integer_info" structure to the class file.
        See Also:
        JVM specification, section 4.4.4
      • addConstantFloatInfo

        public short addConstantFloatInfo​(float value)
        Add a "CONSTANT_Float_info" structure to the class file.
        See Also:
        JVM specification, section 4.4.4
      • addConstantLongInfo

        public short addConstantLongInfo​(long value)
        Add a "CONSTANT_Long_info" structure to the class file.
        See Also:
        JVM specification, section 4.4.5
      • addConstantDoubleInfo

        public short addConstantDoubleInfo​(double value)
        Add a "CONSTANT_Double_info" structure to the class file.
        See Also:
        JVM specification, section 4.4.5
      • addConstantNameAndTypeInfo

        private short addConstantNameAndTypeInfo​(java.lang.String name,
                                                 java.lang.String descriptor)
        Add a "CONSTANT_NameAndType_info" structure to the class file.
        See Also:
        JVM specification, section 4.4.6
      • addConstantUtf8Info

        public short addConstantUtf8Info​(java.lang.String s)
        Adds a "CONSTANT_Utf8_info" structure to the class file if no equal entry exists.
        Returns:
        The index of the already existing or newly created entry
        See Also:
        JVM specification, section 4.4.7
      • addConstantSIFLDInfo

        private short addConstantSIFLDInfo​(java.lang.Object cv)
        Convenience method that adds a String, Integer, Float, Long or Double ConstantInfo.
      • addToConstantPool

        private short addToConstantPool​(ClassFile.ConstantPoolInfo cpi)
        Adds an entry to the constant pool and returns its index, or, if an equal entry already exists in the constant pool, returns the index of that entry.
      • addFieldInfo

        public ClassFile.FieldInfo addFieldInfo​(Java.Modifiers modifiers,
                                                java.lang.String fieldName,
                                                java.lang.String fieldTypeFd,
                                                java.lang.Object optionalConstantValue)
        Creates a ClassFile.FieldInfo and adds it to this class. The return value can be used e.g. to add attributes (Deprecated, ...) to the field.
      • addMethodInfo

        public ClassFile.MethodInfo addMethodInfo​(Java.Modifiers modifiers,
                                                  java.lang.String methodName,
                                                  java.lang.String methodMd)
        Creates a ClassFile.MethodInfo and adds it to this class. The return value can be used e.g. to add attributes (Code, Deprecated, Exceptions, ...) to the method.
      • getConstantPoolInfo

        public ClassFile.ConstantPoolInfo getConstantPoolInfo​(short index)
        Returns:
        The (read-only) constant pool entry indexed by index
      • getConstantPoolSize

        public int getConstantPoolSize()
        Returns:
        The size of the constant pool
      • getConstantUtf8

        public java.lang.String getConstantUtf8​(short index)
        Parameters:
        index - Index to a CONSTANT_Utf8_info in the constant pool
        Returns:
        The string represented by the structure
      • readLengthAndBytes

        private static byte[] readLengthAndBytes​(java.io.DataInputStream dis)
                                          throws java.io.IOException
        u4 length, u1[length]
        Throws:
        java.io.IOException
      • readShortArray

        private static short[] readShortArray​(java.io.DataInputStream dis)
                                       throws java.io.IOException
        u2 length, u2[length]
        Throws:
        java.io.IOException
      • loadConstantPool

        private void loadConstantPool​(java.io.DataInputStream dis)
                               throws java.io.IOException
        u2 constant_pool_count, constant_pool[constant_pool_count]
        Throws:
        java.io.IOException
      • loadFields

        private java.util.List<ClassFile.FieldInfo> loadFields​(java.io.DataInputStream dis)
                                                        throws java.io.IOException
        u2 fields_count, fields[fields_count]
        Throws:
        java.io.IOException
      • buildModsAndAnns

        private static Java.Modifiers buildModsAndAnns​(short mods,
                                                       java.util.List attributes)
        Extract annotations from list of attributes and build a ModifiersAndAnnotations object
        Parameters:
        mods -
        attributes -
      • loadMethods

        private java.util.List<ClassFile.MethodInfo> loadMethods​(java.io.DataInputStream dis)
                                                          throws java.io.IOException
        u2 methods_count, methods[methods_count]
        Throws:
        java.io.IOException
      • loadAttributes

        private java.util.List<ClassFile.AttributeInfo> loadAttributes​(java.io.DataInputStream dis)
                                                                throws java.io.IOException
        u2 attributes_count, attributes[attributes_count]
        Throws:
        java.io.IOException
      • store

        public void store​(java.io.OutputStream os)
                   throws java.io.IOException
        Write ClassFile to an OutputStream, in "class file" format.

        Notice that if an IOException is thrown, the class file is probably written incompletely and thus invalid. The calling method must take care of this situation, e.g. by closing the output stream and then deleting the file.

        Parameters:
        os -
        Throws:
        java.io.IOException
      • storeConstantPool

        private static void storeConstantPool​(java.io.DataOutputStream dos,
                                              java.util.List<ClassFile.ConstantPoolInfo> constantPool)
                                       throws java.io.IOException
        u2 constant_pool_count, constant_pool[constant_pool_count - 1]
        Throws:
        java.io.IOException
      • storeShortArray

        private static void storeShortArray​(java.io.DataOutputStream dos,
                                            short[] sa)
                                     throws java.io.IOException
        u2 count, u2[count]
        Throws:
        java.io.IOException
      • storeFields

        private static void storeFields​(java.io.DataOutputStream dos,
                                        java.util.List<ClassFile.FieldInfo> fieldInfos)
                                 throws java.io.IOException
        u2 fields_count, fields[fields_count]
        Throws:
        java.io.IOException
      • storeMethods

        private static void storeMethods​(java.io.DataOutputStream dos,
                                         java.util.List<ClassFile.MethodInfo> methodInfos)
                                  throws java.io.IOException
        u2 methods_count, methods[methods_count]
        Throws:
        java.io.IOException
      • storeAttributes

        private static void storeAttributes​(java.io.DataOutputStream dos,
                                            java.util.List<ClassFile.AttributeInfo> attributeInfos,
                                            Java.Annotation[] annotations)
                                     throws java.io.IOException
        u2 attributes_count, attributes[attributes_count]
        Throws:
        java.io.IOException
      • getSourceResourceName

        public static java.lang.String getSourceResourceName​(java.lang.String className)
        Construct the name of a resource that could contain the source code of the class with the given name.

        Notice that member types are declared inside a different type, so the relevant source file is that of the outermost declaring class.

        Parameters:
        className - Fully qualified class name, e.g. "pkg1.pkg2.Outer$Inner"
        Returns:
        the name of the resource, e.g. "pkg1/pkg2/Outer.java"
      • getClassFileResourceName

        public static java.lang.String getClassFileResourceName​(java.lang.String className)
        Construct the name of a resource that could contain the class file of the class with the given name.
        Parameters:
        className - Fully qualified class name, e.g. "pkg1.pkg2.Outer$Inner"
        Returns:
        the name of the resource, e.g. "pkg1/pkg2/Outer$Inner.class"
      • toByteArray

        public byte[] toByteArray()
        Return the byte code of this ClassFile as a byte array.
      • loadMethodInfo

        private ClassFile.MethodInfo loadMethodInfo​(java.io.DataInputStream dis)
                                             throws java.io.IOException
        Throws:
        java.io.IOException
      • loadAttribute

        private ClassFile.AttributeInfo loadAttribute​(java.io.DataInputStream dis)
                                               throws java.io.IOException
        Load one class file attribute. The returned object will be of ClassFile.AttributeInfo-derived type, depending on the attribute's name; e.g. if the name of the attribute is "SourceFile", then the returned object will be of type ClassFile.SourceFileAttribute.
        Throws:
        java.io.IOException