Click here to Skip to main content
15,897,371 members
Articles / Web Development / HTML

Java Class Viewer

Rate me:
Please Sign up or sign in to vote.
4.93/5 (41 votes)
21 Jun 2016MIT8 min read 179.3K   7.8K   96  
Watch the Java class file visually & interactively for the meaning of every byte
/*
 * Main.java    Created on Apr 27, 2009
 *
 * Copyright 2009, FreeInternals.org. All rights reserved.
 * Use is subject to license terms.
 */
package org.freeinternals.demo;

import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.freeinternals.classfile.core.AbstractCPInfo;
import org.freeinternals.classfile.core.AccessFlags;
import org.freeinternals.classfile.core.AttributeCount;
import org.freeinternals.classfile.core.AttributeInfo;
import org.freeinternals.classfile.core.CPCount;
import org.freeinternals.classfile.core.ClassFile;
import org.freeinternals.classfile.core.ClassFormatException;
import org.freeinternals.classfile.core.FieldCount;
import org.freeinternals.classfile.core.FieldInfo;
import org.freeinternals.classfile.core.Interface;
import org.freeinternals.classfile.core.InterfaceCount;
import org.freeinternals.classfile.core.MajorVersion;
import org.freeinternals.classfile.core.MethodCount;
import org.freeinternals.classfile.core.MethodInfo;
import org.freeinternals.classfile.core.MinorVersion;
import org.freeinternals.classfile.core.SuperClass;
import org.freeinternals.classfile.core.ThisClass;
import org.freeinternals.classfile.ui.Tool;

/**
 *
 * @author Amos Shi
 */
public class jCFL_CodeDemo {

    /**
     * Before running this application, please ensure the .class file and .jar
     * file exist in the specified location.
     *
     * @param args command line arguments
     */
    public static void main(final String[] args) {
        try {
            jCFL_CodeDemo.extractClassFile();
            jCFL_CodeDemo.extractJarFile();
        } catch (IOException ex) {
            Logger.getLogger(jCFL_CodeDemo.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println(ex.toString());
        } catch (ClassFormatException ex) {
            Logger.getLogger(jCFL_CodeDemo.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println(ex.toString());
        }
    }

    private static void extractClassFile() throws IOException, ClassFormatException {

        File file = new File("C:/Temp/File.class");
        byte[] classByteArray = Tool.readClassFile(file);
        ClassFile classfile = new ClassFile(classByteArray);

        jCFL_CodeDemo.printClassFile(classfile);
    }

    private static void extractJarFile() throws IOException, ClassFormatException {
        File file = new File("C:/Temp/tools.jar");
        JarFile jarFile = new JarFile(file, false, JarFile.OPEN_READ);
        ZipFile zipFile = jarFile;

        final Enumeration zipEntries = zipFile.entries();
        while (zipEntries.hasMoreElements()) {
            ZipEntry zipEntry = (ZipEntry) zipEntries.nextElement();
            if (!zipEntry.getName().endsWith(".class")) {
                continue;
            }

            byte[] classByteArray = Tool.readClassFile(zipFile, zipEntry);
            ClassFile classfile = new ClassFile(classByteArray);

            System.out.println();
            System.out.println(zipEntry.getName());
            jCFL_CodeDemo.printClassFile(classfile);
        }
    }

    private static void printClassFile(ClassFile classfile) {
        // Minor & Major version
        MinorVersion minorVersion = classfile.getMinorVersion();
        System.out.println("Class File Minor Version: " + minorVersion.getValue());

        MajorVersion majorVersion = classfile.getMajorVersion();
        System.out.println("Class File Major Version: " + majorVersion.getValue());

        // Constant Pool
        CPCount cpCount = classfile.getCPCount();
        System.out.println("Constant Pool size: " + cpCount.getValue());

        AbstractCPInfo[] cpArray = classfile.getConstantPool();
        for (int i = 1; i < cpCount.getValue(); i++) {
            System.out.println(
                    String.format("Constant Pool [%d]: %s", i, classfile.getCPDescription(i)));
            short tag = cpArray[i].getTag();
            if ((tag == AbstractCPInfo.CONSTANT_Double) || (tag == AbstractCPInfo.CONSTANT_Long)) {
                i++;
            }
        }

        // Access flag, this & super class
        AccessFlags accessFlags = classfile.getAccessFlags();
        System.out.println("Class Modifier: " + accessFlags.getModifiers());

        ThisClass thisClass = classfile.getThisClass();
        System.out.println("This Class Name Index: " + thisClass.getValue());
        System.out.println("This Class Name: " + classfile.getCPDescription(thisClass.getValue()));

        SuperClass superClass = classfile.getSuperClass();
        System.out.println("Super Class Name Index: " + superClass.getValue());
        if (superClass.getValue() == 0) {
            System.out.println("Super Class Name: java.lang.Object");
        } else {
            System.out.println("Super Class Name: " + classfile.getCPDescription(superClass.getValue()));
        }

        // Interfaces
        InterfaceCount interfactCount = classfile.getInterfacesCount();
        System.out.println("Interface Count: " + interfactCount.getValue());

        if (interfactCount.getValue() > 0) {
            Interface[] interfaceArray = classfile.getInterfaces();
            for (int i = 0; i < interfaceArray.length; i++) {
                System.out.println(
                        String.format("Interface [%d] Name Index: %d", i, interfaceArray[i].getValue()));
                System.out.println(
                        String.format("Interface [%d] Name: %s", i, classfile.getCPDescription(interfaceArray[i].getValue())));
            }
        }

        // Fields
        FieldCount fieldCount = classfile.getFieldCount();
        System.out.println("Field count: " + fieldCount.getValue());

        if (fieldCount.getValue() > 0) {
            FieldInfo[] fieldArray = classfile.getFields();
            for (int i = 0; i < fieldArray.length; i++) {
                System.out.println(String.format("Field [%d]: %s", i, fieldArray[i].getDeclaration()));
            }
        }

        // Methods
        MethodCount methodCount = classfile.getMethodCount();
        System.out.println("Method count: " + methodCount.getValue());

        if (methodCount.getValue() > 0) {
            MethodInfo[] methodArray = classfile.getMethods();
            for (int i = 0; i < methodArray.length; i++) {
                System.out.println(String.format("Method [%d]: %s", i, methodArray[i].getDeclaration()));
            }
        }

        // Attributes
        AttributeCount attributeCount = classfile.getAttributeCount();
        System.out.println("Attribute count: " + attributeCount.getValue());

        AttributeInfo[] attributeArray = classfile.getAttributes();
        for (int i = 0; i < attributeArray.length; i++) {
            System.out.println(String.format("Attribute [%d]: %s", i, attributeArray[i].getName()));
        }

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
Software Developer
United States United States
Deliver useful software to the world.

Comments and Discussions