com.objectwave.classFile
Class ClassFile

java.lang.Object
  |
  +--com.objectwave.classFile.ClassFile

public class ClassFile
extends java.lang.Object

This class is used to manipulate Java class files in strange and mysterious ways. Usage it typically to feed it an array of bytes that are a class file, manipulate the class, then convert the class back into bytes, and feed the final result to defineClass() .

Version:
$Id: ClassFile.java,v 2.2 2002/07/31 15:55:22 dave_hoag Exp $
Author:
dhoag
See Also:
AttributeInfo, ConstantPoolInfo, MethodInfo, FieldInfo

Nested Class Summary
static class ClassFile.Test
           
 
Field Summary
 boolean debug
          Description of the Field
 boolean dumpConstants
          Description of the Field
static int MOD_ABSTRACT
          Description of the Field
static int MOD_FINAL
          Description of the Field
static int MOD_INTERFACE
          Description of the Field
static int MOD_NATIVE
          Description of the Field
static int MOD_PRIVATE
          Description of the Field
static int MOD_PROTECTED
          Description of the Field
static int MOD_PUBLIC
          Description of the Field
static int MOD_STATIC
          Description of the Field
static int MOD_SYNCHRONIZED
          Description of the Field
static int MOD_THREADSAFE
          Description of the Field
static int MOD_TRANSIENT
          Description of the Field
 
Constructor Summary
ClassFile()
           
 
Method Summary
static java.lang.String accessString(short flags)
          Returns a string that represents what the access flags are set for.
 void addAttribute(AttributeInfo newAttribute)
          Add a new optional class Attribute.
 void addAttribute(java.lang.String name, byte[] newData)
          We have to add an item and then get the item so we get the correct ConstantPoolInfo instance.
 short addConstantPoolItem(ConstantPoolInfo item)
          Add a single constant pool item and return its index.
 void addConstantPoolItems(ConstantPoolInfo[] items)
          Add some items to the constant pool.
 java.util.Hashtable allCalledMethods()
           
 boolean checkMagic(java.io.DataInputStream di)
           
 void deleteMethod(java.lang.String name, java.lang.String signature)
          Delete a named method from this class.
 void display(java.io.PrintStream ps)
          Write out a text version of this class.
 AttributeInfo getAttribute(java.lang.String name)
          Return the attribute named 'name' from the class file.
protected static java.io.InputStream getByteCodeStream(java.lang.String path, java.lang.String fName)
           
 java.lang.String[] getClassDependencies()
           
 java.lang.String getClassName()
           
 ConstantPoolInfo getConstantPoolItem(short index)
          Return a constant pool item from this class.
 ConstantPoolInfo getConstantRef(short index)
          Gets the ConstantRef attribute of the ClassFile object
static ClassFile getInstance(java.lang.String classFilePath, java.lang.String className)
          Create a new instance after locating the bytes.
static ClassFile getInstanceWork(java.lang.String pathEntry, java.lang.String className)
          Requires properly formatted parameters.
 java.util.Vector getMethodsCalling(java.lang.String methodName, java.lang.String[] otherClassNames)
           
 java.lang.String getPackageName()
           
 java.lang.String getSourceLocation()
          The source location is the file system resource (file or from a jar) that should enable one to figure out the source of the bytes codes.
 AttributeInfo[] identifyAttributes(java.io.DataInputStream di, ConstantPoolInfo[] constPool)
           
 boolean identifyClassParts(java.io.DataInputStream di, ConstantPoolInfo[] constPool)
           
 FieldInfo[] identifyFields(java.io.DataInputStream di, ConstantPoolInfo[] constPool)
           
 ConstantPoolInfo[] identifyInterfaces(java.io.DataInputStream di, ConstantPoolInfo[] constPool)
           
 MethodInfo[] identifyMethods(java.io.DataInputStream di, ConstantPoolInfo[] constPool)
           
protected  void insertMethod(java.io.InputStream in)
           
protected  boolean isPrimitiveConstant(ConstantPoolInfo item)
           
 void mapClass(java.lang.String oldClass, java.lang.String newClass)
          Map occurences of class oldClass to occurrences of class newClass .
 void mapPackage(java.lang.String oldPackage, java.lang.String newPackage)
          Map occurences of package oldPackage to package newPackage .
static java.lang.String nextSig(java.lang.String sig)
          Returns the next signature from a string of concatenated signatures.
 boolean read(java.io.InputStream in)
          Take an InputStream and read in what is believed to be a class file.
 ConstantPoolInfo[] readConstantPoolInfo(java.io.DataInputStream di)
           
 void readVersion(java.io.DataInputStream di)
           
 ConstantPoolInfo recursiveAdd(ConstantPoolInfo cpi)
          Use recursion to ensure that ConstantPoolInfo dependecies are met.
 void setSourceLocation(java.lang.String str)
          The source location is the file system resource (file or from a jar) that should enable one to figure out the source of the bytes codes.
 java.lang.String toString()
           
static java.lang.String typeString(java.lang.String typeString, java.lang.String varName)
          Takes a type signature and a string representing a variable name and returns a declaration for that variable name.
 void updatePointers(ConstantPoolInfo[] constPool)
          When we read in the class file, we read the 'index' of the constant pool.
 void write(java.io.OutputStream out)
          Write the class out as a stream of bytes to the output stream.
protected  void writeMethod(java.lang.String methodName, java.io.OutputStream out)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

MOD_PUBLIC

public static final int MOD_PUBLIC
Description of the Field

See Also:
Constant Field Values

MOD_PRIVATE

public static final int MOD_PRIVATE
Description of the Field

See Also:
Constant Field Values

MOD_PROTECTED

public static final int MOD_PROTECTED
Description of the Field

See Also:
Constant Field Values

MOD_STATIC

public static final int MOD_STATIC
Description of the Field

See Also:
Constant Field Values

MOD_FINAL

public static final int MOD_FINAL
Description of the Field

See Also:
Constant Field Values

MOD_SYNCHRONIZED

public static final int MOD_SYNCHRONIZED
Description of the Field

See Also:
Constant Field Values

MOD_THREADSAFE

public static final int MOD_THREADSAFE
Description of the Field

See Also:
Constant Field Values

MOD_TRANSIENT

public static final int MOD_TRANSIENT
Description of the Field

See Also:
Constant Field Values

MOD_NATIVE

public static final int MOD_NATIVE
Description of the Field

See Also:
Constant Field Values

MOD_INTERFACE

public static final int MOD_INTERFACE
Description of the Field

See Also:
Constant Field Values

MOD_ABSTRACT

public static final int MOD_ABSTRACT
Description of the Field

See Also:
Constant Field Values

debug

public boolean debug
Description of the Field


dumpConstants

public boolean dumpConstants
Description of the Field

Constructor Detail

ClassFile

public ClassFile()
Method Detail

getInstance

public static ClassFile getInstance(java.lang.String classFilePath,
                                    java.lang.String className)
                             throws java.io.InvalidClassException
Create a new instance after locating the bytes.

Parameters:
classFilePath - A path to search for the provided className.
className - Description of Parameter
Returns:
The Instance value
Throws:
java.io.InvalidClassException - Description of Exception

getInstanceWork

public static ClassFile getInstanceWork(java.lang.String pathEntry,
                                        java.lang.String className)
Requires properly formatted parameters.

Parameters:
className - A file name more than a class name. Like 'com/objectwave/classFile/ClassFile.class'.
pathEntry - An entry in a class path. Like '/home/dhoag/classes'.
Returns:
The InstanceWork value

getByteCodeStream

protected static java.io.InputStream getByteCodeStream(java.lang.String path,
                                                       java.lang.String fName)
Parameters:
path - The entry in the classpath to search
fName - The file for which this class is searching
Returns:
The ByteCodeStream value

accessString

public static java.lang.String accessString(short flags)
Returns a string that represents what the access flags are set for. So 0x14 returns "public final "

Parameters:
flags - Description of Parameter
Returns:
Description of the Returned Value

nextSig

public static java.lang.String nextSig(java.lang.String sig)
Returns the next signature from a string of concatenated signatures. For example if the signature was "[BII", this method would return "II"

Parameters:
sig - Description of Parameter
Returns:
Description of the Returned Value

typeString

public static java.lang.String typeString(java.lang.String typeString,
                                          java.lang.String varName)
Takes a type signature and a string representing a variable name and returns a declaration for that variable name. For example, passing this the strings "[B" and "myArray" will return the string "byte myArray[]"

Parameters:
typeString - Description of Parameter
varName - Description of Parameter
Returns:
Description of the Returned Value

setSourceLocation

public void setSourceLocation(java.lang.String str)
The source location is the file system resource (file or from a jar) that should enable one to figure out the source of the bytes codes.

Parameters:
str - The new SourceLocation value

getPackageName

public java.lang.String getPackageName()
Returns:
The PackageName value

getMethodsCalling

public java.util.Vector getMethodsCalling(java.lang.String methodName,
                                          java.lang.String[] otherClassNames)
Parameters:
methodName - . ( )
otherClassNames - String [] of classes to substitute in the className arg.
Returns:
The MethodsCalling value

getAttribute

public AttributeInfo getAttribute(java.lang.String name)
Return the attribute named 'name' from the class file.

Parameters:
name - Description of Parameter
Returns:
The Attribute value

getClassDependencies

public java.lang.String[] getClassDependencies()
                                        throws java.lang.Exception
Returns:
The ClassDependencies value
Throws:
java.lang.Exception - Description of Exception

getClassName

public java.lang.String getClassName()
Returns:
The ClassName value

getConstantPoolItem

public ConstantPoolInfo getConstantPoolItem(short index)
                                     throws java.lang.Exception
Return a constant pool item from this class. (note does fixup of indexes to facilitate extracting nested or linked items.

Parameters:
index - Description of Parameter
Returns:
The ConstantPoolItem value
Throws:
java.lang.Exception - Description of Exception

getConstantRef

public ConstantPoolInfo getConstantRef(short index)
Gets the ConstantRef attribute of the ClassFile object

Parameters:
index - Description of Parameter
Returns:
The ConstantRef value

isPrimitiveConstant

protected boolean isPrimitiveConstant(ConstantPoolInfo item)
Parameters:
item - Description of Parameter
Returns:
The PrimitiveConstant value

getSourceLocation

public java.lang.String getSourceLocation()
The source location is the file system resource (file or from a jar) that should enable one to figure out the source of the bytes codes.

Returns:
The SourceLocation value

addAttribute

public void addAttribute(AttributeInfo newAttribute)
Add a new optional class Attribute.

Parameters:
newAttribute - The feature to be added to the Attribute attribute

addAttribute

public void addAttribute(java.lang.String name,
                         byte[] newData)
                  throws java.io.IOException,
                         java.lang.Exception
We have to add an item and then get the item so we get the correct ConstantPoolInfo instance.

Parameters:
name - The feature to be added to the Attribute attribute
newData - The feature to be added to the Attribute attribute
Throws:
java.io.IOException - Description of Exception
java.lang.Exception - Description of Exception

recursiveAdd

public ConstantPoolInfo recursiveAdd(ConstantPoolInfo cpi)
                              throws java.lang.Exception
Use recursion to ensure that ConstantPoolInfo dependecies are met.

Parameters:
cpi - Description of Parameter
Returns:
Description of the Returned Value
Throws:
java.lang.Exception - Description of Exception

addConstantPoolItem

public short addConstantPoolItem(ConstantPoolInfo item)
                          throws java.lang.Exception
Add a single constant pool item and return its index. If the item is already in the pool then the index of the preexisting item is returned. Thus you cannot assume that a pointer to your item will be useful.

Parameters:
item - The feature to be added to the ConstantPoolItem attribute
Returns:
Description of the Returned Value
Throws:
java.lang.Exception - Description of Exception

addConstantPoolItems

public void addConstantPoolItems(ConstantPoolInfo[] items)
Add some items to the constant pool. This is used to add new items to the constant pool. The items references in arg1 and arg2 are expected to be valid pointers (if necessary). Pruning is done to prevent adding redundant items to the list and to preserve string space. The algorithm is simple, first identify pool items containing constants in the list of items to be added that are already in the constant pool. If any are found to already exist, change the pointers in the non-constant items to point to the ones in the pool rather than the ones in the list. Next check to see if any of the non-constant items are already in the pool and if so fix up the others in the list to point to the ones in the pool. Finally, add any items (there must be at least one) from the item list that aren't already in the pool, all of the pointers will already be fixed. NOTE: Since constants in the constant pool may be referenced inside the opaque portion of attributes the constant table cannot be re-ordered, only extended.

Parameters:
items - The feature to be added to the ConstantPoolItems attribute

checkMagic

public boolean checkMagic(java.io.DataInputStream di)
                   throws java.io.IOException
Parameters:
di - Description of Parameter
Returns:
Description of the Returned Value
Throws:
java.io.IOException - Description of Exception

deleteMethod

public void deleteMethod(java.lang.String name,
                         java.lang.String signature)
Delete a named method from this class. This method is used to excise specific methods from the loaded class. The actual method code remains, however the method signature is deleted from the constant pool. If this method is called by a class the exception IncompatibleClassChangeException is generated by the runtime.

Parameters:
name - Description of Parameter
signature - Description of Parameter

allCalledMethods

public java.util.Hashtable allCalledMethods()
Returns:
Description of the Returned Value

display

public void display(java.io.PrintStream ps)
             throws java.lang.Exception
Write out a text version of this class.

Parameters:
ps - Description of Parameter
Throws:
java.lang.Exception - Description of Exception

identifyAttributes

public AttributeInfo[] identifyAttributes(java.io.DataInputStream di,
                                          ConstantPoolInfo[] constPool)
                                   throws java.io.IOException
Parameters:
di - Description of Parameter
constPool - Description of Parameter
Returns:
Description of the Returned Value
Throws:
java.io.IOException - Description of Exception

identifyClassParts

public boolean identifyClassParts(java.io.DataInputStream di,
                                  ConstantPoolInfo[] constPool)
                           throws java.io.IOException
Parameters:
di - Description of Parameter
constPool - Description of Parameter
Returns:
Description of the Returned Value
Throws:
java.io.IOException - Description of Exception

identifyFields

public FieldInfo[] identifyFields(java.io.DataInputStream di,
                                  ConstantPoolInfo[] constPool)
                           throws java.io.IOException
Parameters:
di - Description of Parameter
constPool - Description of Parameter
Returns:
Description of the Returned Value
Throws:
java.io.IOException - Description of Exception

identifyInterfaces

public ConstantPoolInfo[] identifyInterfaces(java.io.DataInputStream di,
                                             ConstantPoolInfo[] constPool)
                                      throws java.io.IOException
Parameters:
di - Description of Parameter
constPool - Description of Parameter
Returns:
Description of the Returned Value
Throws:
java.io.IOException - Description of Exception

identifyMethods

public MethodInfo[] identifyMethods(java.io.DataInputStream di,
                                    ConstantPoolInfo[] constPool)
                             throws java.io.IOException
Parameters:
di - Description of Parameter
constPool - Description of Parameter
Returns:
Description of the Returned Value
Throws:
java.io.IOException - Description of Exception

mapClass

public void mapClass(java.lang.String oldClass,
                     java.lang.String newClass)
Map occurences of class oldClass to occurrences of class newClass . This method is used to retarget accesses to one class, seamlessly to another. The format for the class name is slash (/) separated so the class util.ClassFile would be represented as util/ClassFile

Parameters:
oldClass - Description of Parameter
newClass - Description of Parameter

mapPackage

public void mapPackage(java.lang.String oldPackage,
                       java.lang.String newPackage)
Map occurences of package oldPackage to package newPackage . The format for the package name is slash (/) separated so the package java.util would be represented as java/util

Parameters:
oldPackage - Description of Parameter
newPackage - Description of Parameter

read

public boolean read(java.io.InputStream in)
             throws java.io.IOException
Take an InputStream and read in what is believed to be a class file.

Parameters:
in - Description of Parameter
Returns:
boolean True if sucessfully read, False if we failed for some reason.
Throws:
java.io.IOException - Description of Exception

readConstantPoolInfo

public ConstantPoolInfo[] readConstantPoolInfo(java.io.DataInputStream di)
                                        throws java.io.IOException
Parameters:
di - Description of Parameter
Returns:
Description of the Returned Value
Throws:
java.io.IOException - Description of Exception

readVersion

public void readVersion(java.io.DataInputStream di)
                 throws java.io.IOException
Parameters:
di - Description of Parameter
Throws:
java.io.IOException - Description of Exception

toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object
Returns:
Description of the Returned Value

updatePointers

public void updatePointers(ConstantPoolInfo[] constPool)
When we read in the class file, we read the 'index' of the constant pool. This is index1 and index2. Once the entire pool is read in, we can 'updatePointers' to provide references to ConstantPoolInfo objects. This method resolves those instances.

Parameters:
constPool - Description of Parameter

write

public void write(java.io.OutputStream out)
           throws java.io.IOException,
                  java.lang.Exception
Write the class out as a stream of bytes to the output stream. Generally you will read a class file, manipulate it in some way, and then write it out again before passing it to defineClass in some class loader.

Parameters:
out - Description of Parameter
Throws:
java.io.IOException - Description of Exception
java.lang.Exception - Description of Exception

insertMethod

protected void insertMethod(java.io.InputStream in)
                     throws java.io.IOException,
                            java.lang.Exception
Parameters:
in - Description of Parameter
Throws:
java.io.IOException - Description of Exception
java.lang.Exception - Description of Exception

writeMethod

protected void writeMethod(java.lang.String methodName,
                           java.io.OutputStream out)
                    throws java.io.IOException,
                           java.lang.Exception
Parameters:
methodName - Description of Parameter
out - Description of Parameter
Throws:
java.io.IOException - Description of Exception
java.lang.Exception - Description of Exception