Newsletter sign-up
View all newsletters

Sign up for our technology specific newsletters.

Enterprise Java
Email Address:

Take a look inside Java classes

Learn to deduce properties of a Java class from inside a Java program

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone

Page 2 of 6

public interface Application {
    public void main(String args[]);
}


If the above interface was defined, and classes implemented it, then at least you could use the instanceof operator in Java to determine if you had an application or not and thus determine whether or not it was suitable for invoking from the command line. The bottom line is that you can't (define the interface), it wasn't (built into the Java interpreter), and so you can't (determine if a class file is an application easily). So what can you do?

Actually, you can do quite a bit if you know what to look for and how to use it.

Decompiling class files

The Java class file is architecture-neutral, which means it is the same set of bits whether it is loaded from a Windows 95 machine or a Sun Solaris machine. It is also very well documented in the book The Java Virtual Machine Specification by Lindholm and Yellin. The class file structure was designed, in part, to be easily loaded into the SPARC address space. Basically, the class file could be mapped into the virtual address space, then the relative pointers inside the class fixed up, and presto! You had instant class structure. This was less useful on the Intel architecture machines, but the heritage left the class file format easy to comprehend, and even easier to break down.

In the summer of 1994, I was working in the Java group and building what is known as a "least privilege" security model for Java. I had just finished figuring out that what I really wanted to do was to look inside a Java class, excise those pieces that were not allowed by the current privilege level, and then load the result through a custom class loader. It was then that I discovered there weren't any classes in the main run time that knew about the construction of class files. There were versions in the compiler class tree (which had to generate class files from the compiled code), but I was more interested in building something for manipulating pre-existing class files.

I started by building a Java class that could decompose a Java class file that was presented to it on an input stream. I gave it the less-than-original name ClassFile. The beginning of this class is shown below.

public class ClassFile {
    int                 magic;
    short               majorVersion;
    short               minorVersion;
    ConstantPoolInfo    constantPool[];
    short               accessFlags;
    ConstantPoolInfo    thisClass;
    ConstantPoolInfo    superClass;
    ConstantPoolInfo    interfaces[];
    FieldInfo           fields[];
    MethodInfo          methods[];
    AttributeInfo       attributes[];
    boolean             isValidClass = false;
    public static final int ACC_PUBLIC      = 0x1;
    public static final int ACC_PRIVATE     = 0x2;
    public static final int ACC_PROTECTED   = 0x4;
    public static final int ACC_STATIC      = 0x8;
    public static final int ACC_FINAL       = 0x10;
    public static final int ACC_SYNCHRONIZED    = 0x20;
    public static final int ACC_THREADSAFE  = 0x40;
    public static final int ACC_TRANSIENT   = 0x80;
    public static final int ACC_NATIVE      = 0x100;
    public static final int ACC_INTERFACE   = 0x200;
    public static final int ACC_ABSTRACT    = 0x400;


As you can see, the instance variables for class ClassFile define the major components of a Java class file. In particular, the central data structure for a Java class file is known as the constant pool. Other interesting chunks of class file get classes of their own: MethodInfo for methods, FieldInfo for fields (which are the variable declarations in the class), AttributeInfo to hold class file attributes, and a set of constants that was taken directly from the specification on class files to decode the various modifiers that apply to field, method, and class declarations.

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comment
Login
Forgot your account info?
Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources
  • "SBKTech Tools" -- Cool tools that take advantage of class file knowledge. http://www.sbktech.org/
  • Source files for this column:
  • "How to build an interpreter in Java, Part 2The structure"
    The trick to assembling the foundation classes for a simple interpreter. http://www.javaworld.com/javaworld/jw-06-1997/jw-06-indepth.html
  • "How to build an interpreter in Java, Part 1The BASICs"
    For complex applications requiring a scripting language, Java can be used to implement the interpreter, adding scripting abilities to any Java app. http://www.javaworld.com/javaworld/jw-05-1997/jw-05-indepth.html
  • "Lexical analysis, Part 2Build an application"
    How to use the StreamTokenizer object to implement an interactive calculator. http://www.javaworld.com/javaworld/jw-02-1997/jw-02-indepth.html
  • "Lexical analysis and JavaPart 1"
    Learn how to convert human-readable text into machine-readable data using the StringTokenizer and StreamTokenizer classes. http://www.javaworld.com/javaworld/jw-01-1997/jw-01-indepth.html
  • "Code reuse and object-oriented systems"
    Use a helper class to enforce dynamic behavior. http://www.javaworld.com/javaworld/jw-12-1996/jw-12-indepth.html
  • "Container support for objects in Java 1.0.2"
    Organizing objects is easy when you put them into containers. This article walks you through the design and implementation of a container. http://www.javaworld.com/javaworld/jw-11-1996/jw-11-indepth.html
  • "The basics of Java class loaders"
    The fundamentals of this key component of the Java architecture. http://www.javaworld.com/javaworld/jw-10-1996/jw-10-indepth.html
  • "Not using garbage collection"
    Minimize heap thrashing in your Java programs. http://www.javaworld.com/javaworld/jw-09-1996/jw-09-indepth.html
  • "Threads and applets and visual controls"
    This final part of the series explores reading multiple data channels. http://www.javaworld.com/javaworld/jw-07-1996/jw-07-mcmanis.html
  • "Using communication channels in applets, Part 3"
    Develop Visual Basic-style techniques to applet design -- and convert temperatures in the process. http://www.javaworld.com/javaworld/jw-06-1996/jw-06-mcmanis.html
  • "Synchronizing threads in Java, Part II"
    Learn how to write a data channel class, and then create a simple example application that illustrates a real-world implementation of the class. http://www.javaworld.com/javaworld/jw-05-1996/jw-05-mcmanis.html
  • "Synchronizing threads in Java"
    Former Java team developer Chuck McManis walks you through a simple example illustrating how to synchronize threads to assure reliable and predictable applet behavior. http://www.javaworld.com/javaworld/jw-04-1996/jw-04-synch.html