classpath
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

IMPLEMENTATION (was, Re: jdiff.sh)


From: C. Scott Ananian
Subject: IMPLEMENTATION (was, Re: jdiff.sh)
Date: Fri, 20 Sep 2002 21:03:24 -0400 (EDT)

The attached program, less than 100 lines long, built using the FLEX
compiler infrastructure, does what you want (well, no automagic patching
of classpath code).  It can be compiled and linked against a binary or
source distribution of FLEX from http://flex-compiler.lcs.mit.edu,
or you can simply use the attached jar 'listall.jar'.

Generating an API listing for classpath 0.04 (debian package 0.04-5):
% java -jar listall.jar /usr/share/classpath/glibj.zip | sort -u > cp-sorted

Generating a listing for Sun jdk1.4.0 is a little more involved, because
the Sun jdk mentions classes not present in the .jar:
(you will have to tweak the paths to correspond to your installation of
the jdk)
% java -Xmx768m 
-Dharpoon.class.path=/home/cananian/j2sdk1.4.0/jre/lib/jce.jar:/home/cananian/j2sdk1.4.0/jre/lib/charsets.jar
 -jar listall.jar ~/j2sdk1.4.0/jre/lib/rt.jar | sort -u > jdk-sorted

Generating a listing for libgcj-3.2.1 (debian version 1:3.2.1ds1-0pre2):
% java -jar listall.jar /usr/share/java/libgcj-3.2.1.jar | sort -u > gcj-sorted

Finding the differences:
% diff -u jdk-sorted cp-sorted
% diff -u gcj-sorted cp-sorted

The tool only lists public methods of public classes, suppresses classes
in sun.*, com.sun.* and gnu.* packages, and lists the 'defining' copy of
each method; that is, if a method B.m overrides A.m, it lists A.m, not
B.m.

The first diff between jdk-sorted and cp-sorted is:

-java.applet.AppletContext.setStream(Ljava/lang/String;Ljava/io/InputStream;)V
+java.applet.AppletContext.setString(Ljava/lang/String;Ljava/io/InputStream;)V

It is obvious from this that GNU classpath has named this method
incorrectly.  Some more missing methods follow, then:

-java.awt.Component.isFocusCycleRoot(Ljava/awt/Container;)Z
+java.awt.Component.isFocusCycleRoot()Z

Here GNU Classpath has an incorrect method signature.

The useful output goes on from here. (see attached)
 --scott

President SSBN 743 India IDEA COBRA JANE atomic Pakistan ASW corporate 
globalization 
pending AP Secretary affinity group Ft. Meade North Korea MI5 Suharto 
                         ( http://cscott.net/ )

----- class ListAll.java ----
// ListAll.java, created Fri Sep 20 19:55:10 2002 by cananian
// Copyright (C) 2000 C. Scott Ananian <address@hidden>
// Licensed under the terms of the GNU GPL; see COPYING for details.
package harpoon.Main;

import harpoon.Analysis.AbstractClassFixupRelinker;
import harpoon.ClassFile.HClass;
import harpoon.ClassFile.HConstructor;
import harpoon.ClassFile.HMethod;
import harpoon.ClassFile.Linker;
import harpoon.ClassFile.Loader;
import harpoon.Util.ArrayIterator;
import harpoon.Util.EnumerationIterator;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.Iterator;
import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
/**
 * <code>ListAll</code>
 * 
 * @author  C. Scott Ananian <address@hidden>
 * @version $Id$
 */
public class ListAll {
    static Linker linker;
    public static void main(String[] args) throws IOException {
        // first argument should be a .jar file.
        String hcp = System.getProperty("harpoon.class.path");
        hcp = (hcp==null) ? args[0] : args[0]+":"+hcp;
        System.setProperty("harpoon.class.path", hcp);
        // use a fixup relinker
        linker = new AbstractClassFixupRelinker(Loader.systemLinker);
        // iterator through all classes in the .jar
        String filesep   = System.getProperty("file.separator");
        ZipFile zf = new ZipFile(args[0]);
        for (Iterator it=new EnumerationIterator(zf.entries());
             it.hasNext(); ) {
            ZipEntry ze = (ZipEntry) it.next();
            if (ze.isDirectory()) continue;
            String name = ze.getName();
            int i = name.lastIndexOf(".class");
            if (i<0) continue;
            doOne(name.substring(0, i).replace(filesep.charAt(0), '.'));
        }
    }
    static void doOne(String classname) {
        HClass hc = linker.forName(classname);
        // if class is not public, skip it.
        if (!Modifier.isPublic(hc.getModifiers())) return;
        // skip classes starting 'sun.', 'com.sun', or 'gnu.'
        if (classname.startsWith("sun.")) return;
        if (classname.startsWith("com.sun.")) return;
        if (classname.startsWith("gnu.")) return;
        // print all methods of the class.
        for (Iterator it = new ArrayIterator(hc.getDeclaredMethods());
             it.hasNext(); ) {
            HMethod hm = (HMethod) it.next();
            // if method is not public, skip it.
            if (!Modifier.isPublic(hm.getModifiers())) continue;
            doOne(hm);
        }
    }
    static void doOne(HMethod hm) {
        // only print the canonical name of the method: the top-most
        // superclass which declares it.
        int m = hm.getModifiers();
        if (Modifier.isStatic(m) || Modifier.isPrivate(m) ||
            hm instanceof HConstructor)
            /* leave hm well enough alone */;
        else for (HClass hc=hm.getDeclaringClass(); hc!=null;
                  hc=hc.getSuperclass())
            try {
                hm = hc.getMethod(hm.getName(), hm.getDescriptor());
                hc = hm.getDeclaringClass();
            } catch (NoSuchMethodError e) {
                break;
            }
        // pretty-print
        System.out.println(toString(hm));
    }

    static String toString(HMethod hm) {
        StringBuffer sb = new StringBuffer();
        sb.append(hm.getDeclaringClass().getName());
        sb.append('.');
        sb.append(hm.getName());
        sb.append(hm.getDescriptor());
        return sb.toString();
    }
}

Attachment: listall.jar
Description: Binary archive of listall tool.

Attachment: jdk-sorted
Description: Public API methods in JDK 1.4.0

Attachment: cp-sorted
Description: Public API methods in GNU classpath 0.04

Attachment: gcj-sorted
Description: Public API methods in libgcj 3.2.1


reply via email to

[Prev in Thread] Current Thread [Next in Thread]