mitoolkit.core
Class ClassInspector

java.lang.Object
  extended bymitoolkit.core.ClassInspector
All Implemented Interfaces:
ClassClosureConstants

public class ClassInspector
extends java.lang.Object
implements ClassClosureConstants

Utilities for retrieving information about the classes that are declared and referenced by a given class, thus allowing to determine its class closure.

java.lang.Classprovides methods that enable reflection and allow to retrieve information about a class object. Nevertheless, some of the methods are only defined but not implemented in JDK 1.1.
This is the case of Class.getDeclaredClasses(), that retrieves the set of types that are declared by the class it operates on. A class C' is declared by a class C if it is either:

A similar functionality is provided by the method getDeclaredClasses provided by this class.

The method Class.getClasses(), instead, computes the transitive closure of declared classes. The declared class closure C* of a class C is such that:

  1. C belongs to C *;
  2. a class C' belongs to C if it exists c belonging to C* such that C' is either:
A similar functionality is provided by the method getDeclaredClassClosure provided by this class. Actually, this method returns a broader closure than java.lang.class.getClasses, in that the latter considers only public classes, while the former considers all the classes that are declared, independently from their access modifier.

Even with an implementation the aforementioned methods, however, some key functionality is still missing in java.lang.Class. More precisely, there is no way to retrieve the classes that are not declared as part of a member of a class, and yet are referenced within it. Let us consider the following example:

 
  public MySuper implements MySuperInterface {
    private MySuperField sf;
    public void m() {
      MySuperVar s = new MySuperVar();
      ...
    }
  }
  public MyClass extends MySuper implements MyInterface {
    protected MyField f;
    private class MyInnerClass {...}
    public MyReturn myMethod(MyPar p) throws MyException {
      MyVar v = new MyVar();
      ...
    }
  }
  
 
The classes and interfaces MyClass, MyInterface, MyField, MyReturn, MyPar, MyException, and MyInnerClass belong to the set of classes declared by MyClass. The classes above, plus MySuper, MySuperInterface, and MySuperField (and void and java.lang.Object ...) belong instead to the declared class closure of MyClass.

Nevertheless, the class MyVar is referenced by MyClass (and, as such, it is necessary to a correct execution of MyClass) but there is no method in any of the java.lang.* packages that allows retrieval of this class.
This functionality is provided by two methods in ClassInspector. ClassInspector#getReferencedClassesgetReferencedClasses retrieves the set of classes that are either declared or referenced by a given class. Thus, it would retrieve MyVar in the example above. ClassInspector#getFullClassClosuregetFullClassClosure determines the complete transitive closure of a given class. The complete transitive closure C* of a class C is such that:

  1. C belongs to C *;
  2. a class C' belongs to C if it exists c belonging to C* such that C' is either:
Thus, getFullClassClosure would capture also MySuperVar in MySuper, as part of the closure of MyClass. In other words, getFullClassClosure allows to determine the complete set of classes that are needed for the execution of a given class .

Notably, all the methods provided by ClassInspector accept a µ Server as an additional parameter, besides the Class to be inspected. This allows ClassInspector to filter out classes that are considered ubiquitous within the specified µ Server. Thus, for instance, void and java.lang.Object would not be included in the declared class closure computed in the previous example.
Finally, ClassInspector provides a number of other convenience methods. In particular, getClassClosure allows to retrieve the different kinds of class closure described thus far by using the same method, with the desidered closure identified by a parameter. This allows to create easily relocation primitives that can let the user specify the amount of classes to be transferred.

Acknowledgments: the method getReferencedClasses has been developed by Jason Ginchereau, while he was working in my former group at Washington University on a student research project involving µ Code.

Version:
1.0
Author:
Jason Ginchereau, Gian Pietro Picco
See Also:
mucode.util.ClosureConstants

Field Summary
private static byte CONSTANT_Class
           
private static byte CONSTANT_Double
           
private static byte CONSTANT_Fieldref
           
private static byte CONSTANT_Float
           
private static byte CONSTANT_Integer
           
private static byte CONSTANT_InterfaceMethodref
           
private static byte CONSTANT_Long
           
private static byte CONSTANT_Methodref
           
private static byte CONSTANT_NameAndType
           
private static byte CONSTANT_String
           
private static byte CONSTANT_Utf8
           
private static java.lang.String ERRMSG
           
 
Fields inherited from interface mitoolkit.core.ClassClosureConstants
DECLARED, DECLAREDCLOSURE, FULLCLOSURE, NONE, REFERENCED, ROOT
 
Constructor Summary
private ClassInspector()
           
 
Method Summary
private static void addByteCode(java.lang.String className, byte[] bc, java.util.Hashtable classes)
           
private static void addClass(java.lang.Class c, java.util.Hashtable classes)
           
private static void addClasses(java.lang.Class[] cs, java.util.Hashtable classes)
           
private static void filterMember(java.lang.Class c, java.util.Vector v)
           
private static void filterMembers(java.lang.Class[] c, java.util.Vector v)
           
private static void filterMembers(java.util.Vector v)
           
private static java.lang.Class[] filterUbiquitous(java.lang.Class[] classes)
          Filter out classes that are considered ubiquitous in the specified µ Server.
private static java.lang.String[] filterUbiquitous(java.lang.String[] classes)
          Filter out classes that are considered ubiquitous in the specified µ Server.
static java.util.Hashtable getClassClosure(java.lang.Class c, int closureType)
          Compute, within a given µ Server, the class closure of the specified class, as specified by the closureType parameter.
static void getClassClosure(java.lang.Class c, int closureType, java.util.Hashtable classes)
           
private static java.lang.String[] getClassNames(java.lang.Class[] classes)
          Return the class names of the specified class objects.
static java.util.Hashtable getDeclaredClassClosure(java.lang.Class c)
          Returns an array containing class objects representing all the classes and interfaces that are members of the class represented by the specified class object.
static java.util.Hashtable getDeclaredClassClosure(java.lang.Class c, java.util.Hashtable classHash)
           
private static void getDeclaredClassClosure(java.lang.Class classObj, java.util.Vector classes)
           
private static void getDeclaredClassClosure(java.lang.Class classObj, java.util.Vector classes, java.util.Hashtable classHash)
           
static java.util.Hashtable getDeclaredClasses(java.lang.Class c)
          Returns an array of class objects reflecting all the classes and interfaces declared as members of the class represented by the specified class object.
private static java.lang.String[] getDeclaredClasses(java.lang.Class c, boolean b)
           
static java.util.Hashtable getDeclaredClasses(java.lang.Class c, java.util.Hashtable classes)
           
private static java.util.Hashtable getFullClassClosure(java.lang.Class c)
          Retrieve the full class closure of the given class.
private static java.util.Hashtable getFullClassClosure(java.lang.Class c, java.util.Hashtable classes)
           
private static void getFullClassClosure(MobileClassLoader currentLoader, java.lang.Class c, byte[] bytecode, java.util.Hashtable classes)
           
static java.util.Hashtable getReferencedClasses(java.lang.Class c)
          Retrieve all the classes that are referenced by a given class.
private static java.lang.String[] getReferencedClasses(java.lang.Class c, byte[] bytecode)
          Reads the bytecode of a class and returns the names of all classes referenced by it in any way.
static java.util.Hashtable getReferencedClasses(java.lang.Class c, java.util.Hashtable classes)
           
static java.util.Hashtable getRoot(java.lang.Class c)
           
static java.util.Hashtable getRoot(java.lang.Class c, java.util.Hashtable h)
           
private static boolean isPrimitive(java.lang.String className)
          Return true if the class name refers to a primitive type (i.e., boolean, byte, char, short, int, long, float, double, void), false otherwise.
private static void processMember(java.lang.Class c, java.util.Vector v)
           
private static void processMembers(java.lang.Class[] c, java.util.Vector v)
           
private static boolean skip(java.lang.Class classObj)
           
private static boolean skip(java.lang.Class classObj, java.util.Hashtable classes)
           
private static boolean skip(java.lang.String className)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

CONSTANT_NameAndType

private static final byte CONSTANT_NameAndType
See Also:
Constant Field Values

CONSTANT_Utf8

private static final byte CONSTANT_Utf8
See Also:
Constant Field Values

CONSTANT_Integer

private static final byte CONSTANT_Integer
See Also:
Constant Field Values

CONSTANT_Float

private static final byte CONSTANT_Float
See Also:
Constant Field Values

CONSTANT_Long

private static final byte CONSTANT_Long
See Also:
Constant Field Values

CONSTANT_Double

private static final byte CONSTANT_Double
See Also:
Constant Field Values

CONSTANT_Class

private static final byte CONSTANT_Class
See Also:
Constant Field Values

CONSTANT_String

private static final byte CONSTANT_String
See Also:
Constant Field Values

CONSTANT_Fieldref

private static final byte CONSTANT_Fieldref
See Also:
Constant Field Values

CONSTANT_Methodref

private static final byte CONSTANT_Methodref
See Also:
Constant Field Values

CONSTANT_InterfaceMethodref

private static final byte CONSTANT_InterfaceMethodref
See Also:
Constant Field Values

ERRMSG

private static final java.lang.String ERRMSG
See Also:
Constant Field Values
Constructor Detail

ClassInspector

private ClassInspector()
Method Detail

getClassClosure

public static java.util.Hashtable getClassClosure(java.lang.Class c,
                                                  int closureType)
                                           throws java.lang.ClassNotFoundException
Compute, within a given µ Server, the class closure of the specified class, as specified by the closureType parameter. Acceptable values for this parameter are defined in ClosureConstants, and are NONE, ROOT, DECLARED, REFERENCED, DECLAREDCLOSURE, FULLCLOSURE. Essentially, this method delegates the computation to the appropriate method contained in this class.
Classes that belong to the closure but are considered ubiquitous in the specified µ Server are not returned as part of the result.

Parameters:
closureType - the kind of closure that must be computed
Returns:
the class objects belonging to the closure
Throws:
java.lang.ClassNotFoundException - if the class cannot be resolved

getClassClosure

public static void getClassClosure(java.lang.Class c,
                                   int closureType,
                                   java.util.Hashtable classes)
                            throws java.lang.ClassNotFoundException
Throws:
java.lang.ClassNotFoundException

getRoot

public static java.util.Hashtable getRoot(java.lang.Class c)
                                   throws java.io.IOException
Throws:
java.io.IOException

getRoot

public static java.util.Hashtable getRoot(java.lang.Class c,
                                          java.util.Hashtable h)
                                   throws java.io.IOException
Throws:
java.io.IOException

getDeclaredClasses

public static java.util.Hashtable getDeclaredClasses(java.lang.Class c)
                                              throws java.io.IOException
Returns an array of class objects reflecting all the classes and interfaces declared as members of the class represented by the specified class object. This includes public, protected, default (package) access, and private classes and interfaces declared by the class, but excludes inherited classes and interfaces. This method returns an array of length 0 if the class declares no classes or interfaces as 2members, or if the class object represents a primitive type (including void) or an array class. Classes that belong to the closure but are considered ubiquitous in the specified µ Server are not returned as part of the result.

Parameters:
c - the class object whose closure must be computed
Returns:
the class objects belonging to the closure
Throws:
java.io.IOException

getDeclaredClasses

public static java.util.Hashtable getDeclaredClasses(java.lang.Class c,
                                                     java.util.Hashtable classes)
                                              throws java.io.IOException
Throws:
java.io.IOException

getDeclaredClassClosure

public static java.util.Hashtable getDeclaredClassClosure(java.lang.Class c)
                                                   throws java.lang.ClassNotFoundException,
                                                          java.io.IOException
Returns an array containing class objects representing all the classes and interfaces that are members of the class represented by the specified class object. This includes public, protected, default (package), and private class and interface members inherited from superclasses as well as class and interface members declared by the class. Returns an array of length 0 if this class object represents a primitive type (including void).
Classes that belong to the closure but are considered ubiquitous in the specified µ Server are not returned as part of the result.

Parameters:
c - the class object whose closure must be computed
Returns:
the class objects belonging to the closure
Throws:
java.lang.ClassNotFoundException
java.io.IOException

getDeclaredClassClosure

public static java.util.Hashtable getDeclaredClassClosure(java.lang.Class c,
                                                          java.util.Hashtable classHash)
                                                   throws java.lang.ClassNotFoundException,
                                                          java.io.IOException
Throws:
java.lang.ClassNotFoundException
java.io.IOException

getReferencedClasses

public static java.util.Hashtable getReferencedClasses(java.lang.Class c)
                                                throws java.lang.ClassNotFoundException,
                                                       java.io.IOException
Retrieve all the classes that are referenced by a given class. These classes include the declared ones (i.e., those returned by getDeclaredClasses), the superclass, the interfaces implemented by this class, and the classes that are used by the class (e.g., declared in the body of a method) but not declared in the members. Classes that belong to the closure but are considered ubiquitous in the specified µ Server are not returned as part of the result.

Parameters:
c - the class object whose closure must be computed
Returns:
the class objects belonging to the closure
Throws:
java.lang.ClassNotFoundException
java.io.IOException

getReferencedClasses

public static java.util.Hashtable getReferencedClasses(java.lang.Class c,
                                                       java.util.Hashtable classes)
                                                throws java.lang.ClassNotFoundException,
                                                       java.io.IOException
Throws:
java.lang.ClassNotFoundException
java.io.IOException

getFullClassClosure

private static java.util.Hashtable getFullClassClosure(java.lang.Class c)
                                                throws java.lang.ClassNotFoundException,
                                                       java.io.IOException
Retrieve the full class closure of the given class. The closure is composed by the class itself, by its referenced classes, by their referenced classes, and so on recursively. Classes that belong to the closure but are considered ubiquitous in the specified µ Server are not returned as part of the result.

Parameters:
c - the class object whose closure must be computed
Returns:
the class objects belonging to the closure
Throws:
java.lang.ClassNotFoundException
java.io.IOException

getFullClassClosure

private static java.util.Hashtable getFullClassClosure(java.lang.Class c,
                                                       java.util.Hashtable classes)
                                                throws java.lang.ClassNotFoundException,
                                                       java.io.IOException
Throws:
java.lang.ClassNotFoundException
java.io.IOException

getClassNames

private static java.lang.String[] getClassNames(java.lang.Class[] classes)
Return the class names of the specified class objects.

Parameters:
classes - an array of class objects
Returns:
an array containing, in order, the corresponding class names.

filterUbiquitous

private static java.lang.Class[] filterUbiquitous(java.lang.Class[] classes)
Filter out classes that are considered ubiquitous in the specified µ Server.

Parameters:
classes - an array of class objects to be filtered
Returns:
an array of class objects that are not considered ubiquitous in server.

filterUbiquitous

private static java.lang.String[] filterUbiquitous(java.lang.String[] classes)
Filter out classes that are considered ubiquitous in the specified µ Server.

Parameters:
classes - an array of class names to be filtered
Returns:
an array of class names that are not considered ubiquitous in server.

isPrimitive

private static boolean isPrimitive(java.lang.String className)
Return true if the class name refers to a primitive type (i.e., boolean, byte, char, short, int, long, float, double, void), false otherwise.


filterMember

private static void filterMember(java.lang.Class c,
                                 java.util.Vector v)

filterMembers

private static void filterMembers(java.lang.Class[] c,
                                  java.util.Vector v)

filterMembers

private static void filterMembers(java.util.Vector v)

processMember

private static void processMember(java.lang.Class c,
                                  java.util.Vector v)

processMembers

private static void processMembers(java.lang.Class[] c,
                                   java.util.Vector v)

getFullClassClosure

private static void getFullClassClosure(MobileClassLoader currentLoader,
                                        java.lang.Class c,
                                        byte[] bytecode,
                                        java.util.Hashtable classes)
                                 throws java.lang.ClassNotFoundException,
                                        java.io.IOException
Throws:
java.lang.ClassNotFoundException
java.io.IOException

getReferencedClasses

private static java.lang.String[] getReferencedClasses(java.lang.Class c,
                                                       byte[] bytecode)
                                                throws java.io.IOException
Reads the bytecode of a class and returns the names of all classes referenced by it in any way.

Note: it does NOT check for classes refrenced by superclasses. However, the direct superclass will always be in the list of names returned.

Returns:
an array of all class names referenced in the bytecode
Throws:
java.io.IOException - if there is some problem reading the bytecode

getDeclaredClasses

private static java.lang.String[] getDeclaredClasses(java.lang.Class c,
                                                     boolean b)

getDeclaredClassClosure

private static void getDeclaredClassClosure(java.lang.Class classObj,
                                            java.util.Vector classes)
                                     throws java.lang.ClassNotFoundException
Throws:
java.lang.ClassNotFoundException

getDeclaredClassClosure

private static void getDeclaredClassClosure(java.lang.Class classObj,
                                            java.util.Vector classes,
                                            java.util.Hashtable classHash)
                                     throws java.lang.ClassNotFoundException
Throws:
java.lang.ClassNotFoundException

skip

private static boolean skip(java.lang.String className)

skip

private static boolean skip(java.lang.Class classObj)

skip

private static boolean skip(java.lang.Class classObj,
                            java.util.Hashtable classes)

addByteCode

private static void addByteCode(java.lang.String className,
                                byte[] bc,
                                java.util.Hashtable classes)

addClass

private static void addClass(java.lang.Class c,
                             java.util.Hashtable classes)
                      throws java.io.IOException
Throws:
java.io.IOException

addClasses

private static void addClasses(java.lang.Class[] cs,
                               java.util.Hashtable classes)
                        throws java.io.IOException
Throws:
java.io.IOException