Search code examples
javajartrace

JAVA - how to print trace of methods/objects used from an external jar


I'm currently testing api's that are given to us in a jar. I am attempting to get a 'coverage' or list of the jar-methods and objects that we have touched or that at least our source code references.

What we have or will have available is a text format of "here is a list of API's"

And we need to cross reference our own application to ensure we are covering the API's listed.

...

Here's a simplified example... Below I listed an example of the external code available from the jar, and the code we have using those APIs.

-- EXTERNAL_USE_CLASS -- MOCKS the external JAR with public API's that we need to cover

package external_api;

public class EXTERNAL_USE_CLASS {
    String myString;
    Integer myInteger;
    Boolean has_ran;
    public EXTERNAL_USE_CLASS() {
        myString = "initial_string";
        myInteger = 4;
        has_ran = false;
    }
    public String getMyString() {
        return myString;
    }
    public void setMyString(String myString) {
        this.myString = myString;
    }
    public Integer getMyInteger() {
        return myInteger;
    }
    public void setMyInteger(Integer myInteger) {
        this.myInteger = myInteger;
    }
    public Boolean getHas_ran() {
        return has_ran;
    }
    public void setHas_ran(Boolean has_ran) {
        this.has_ran = has_ran;
    }
}

My project will import the above as a jar and add it to the build path. What my code will do, is something like this:

UseExtJar -- mocks our test application using the external jars objects/mathods

import external_api.EXTERNAL_USE_CLASS;

public class UseExtJar {
    static EXTERNAL_USE_CLASS u = new EXTERNAL_USE_CLASS();

    //below is callable via a CLI interface test APP.
    public static void test_basics() {
        Boolean hasRan = u.getHas_ran();
        Integer getInt = u.getMyInteger();
        String getString = u.getMyString();
        System.out.println("u.getHas_ran()"+hasRan);
        System.out.println("u.getMyInteger()"+getInt);
        System.out.println("u.getMyString()"+getString);
    }
}

And what I am interested in exposing are all the API's touched from the external Jar.

(which namely would these lines)

    Boolean hasRan = u.getHas_ran();
    Integer getInt = u.getMyInteger();
    String getString = u.getMyString();

And If possible... I'd like to be able to print out some report to the effect of saying

Your Object Method 'test_basics' has used the following api's:
--external_api.EXTERNAL_USE_CLASS.getHas_ran()
--external_api.EXTERNAL_USE_CLASS.getMyInteger() --external_api.EXTERNAL_USE_CLASS.getMyString()

The above names I had to get by going to my test-class and right clicking in eclipse and saying 'copy qualified name'.

Which is kind of a pain if we have to do this for 1,000's of APIs.... I just figured theres some way to logically print out a trace.

It could be I just dont know the proper google search terms, and this is a common easy task.

Much Appreciated for any help/pointers.


Solution

  • Thanks.

    I started with reflection as you suggested, and then drifted towards ASM because I'm working with bytecode.


    I pulled my reference from 2 links referencing ASM and reflection

    Java: Easy way to get method stub out of class files within a JAR file? Reflection?

    How can I find all the methods that call a given method in Java?


    My solution essentially solves the problem in 2 steps

    1. read all the target-methods from the external-jar

    via ASM, read in all class/method objects that are public that satisfy a class path (com.my.class.object.*) and some opt-code filters (not private, not abstract, etc) and append all that satisfy the filtering to a list of objects storing the class/method.

    2. foreach target-method, check if its existent in our source code.

    For each target class/method found, just as the link provided above does, I can check where, and print all the occurances with line/filenames etc.