How to identify a missing method (Binary Compatibi

2019-01-17 01:04发布

I want to verify binary compatibility between 2 JARs.

Following the suggestions in this answer I used jboss tattletale but it can find only missing classes.

How can I find if there are missing methods? Is it possible at all?

E.g.

"Depends - on" class Foo depends on Bar (like many other middle class workers)

import org.overlyusedclassnames.Bar

public class Foo{
    public void someMethod(){
         Bar tender = new Bar();
         tender.getJohnnyRedLabel();
         tender.getJohnnyBlueLabel(); //this method is new in the Bar class
    }
}

"Compile time" class

package org.overlyusedclassnames;

/** 
 * @Since 1992
 * Changes: added blue and gold Johnny Walker labels
 */

public class Bar {
    public Drink getJohnnyRedLabel(){
         return new JohnyWalkerFactory.get(RedLabel.class);
    }

    public Drink getJohnnyBlackLabel(){
         return new JohnyWalkerFactory.get(BlackLabel.class);
    }

    public Drink getJohnnyGoldLabel(){
         return new JohnyWalkerFactory.get(GoldLabel.class);
    }

    public Drink getJohnnyBlueLabel(){
         return new JohnyWalkerFactory.get(BlueLabel.class);
    }

}

Now imagine an old Bar jar is accedently replacing the compiled time bar:

"Runtime time" class

package org.overlyusedclassnames;

/** 
 * @Since 1909
 * Changes: added red and black Johnny Walker labels
 */

public class Bar {
    public Drink getJohnnyRedLabel(){
         return new JohnyWalkerFactory.get(RedLabel.class);
    }

    public Drink getJohnnyBlackLabel(){
         return new JohnyWalkerFactory.get(BlackLabel.class);
    }
}

Is there a way to identify the missing method without running it and getting a NoSuchMethodError?


Disclaimer: This is a major rephrasing of my own related question, which is undeletable. I chose asking a new question because the rephrasing will render the current 2 answers as quite unrelated to the topic.

6条回答
贪生不怕死
2楼-- · 2019-01-17 01:38

japi-compliance-checker - backward API/ABI compatibility checker for a Java library:

japi-compliance-checker -lib NAME -old OLD.jar -new NEW.jar

enter image description here

sigtest - Oracle's SigTest signature testing and API conformance tool

japitools - test for compatibility between Java APIs

japi-checker - a java API backward compatibility checker which works at binary level

revapi - API analysis and change tracking tool

or manually using javap decompiler:

javap OLD.class > OLD.txt
javap NEW.class > NEW.txt
diff -rNau OLD.txt NEW.txt > CHANGES.txt
查看更多
淡お忘
3楼-- · 2019-01-17 01:40

Clirr - checks Java libraries for binary and source compatibility with older releases:

java -jar clirr-core-0.6-uber.jar -o OLD.jar -n NEW.jar
查看更多
一夜七次
4楼-- · 2019-01-17 01:45

japicmp is another tool for checking binary compatibility. It is available as standalone command line tool or as maven plugin.

查看更多
我只想做你的唯一
5楼-- · 2019-01-17 01:51

Revapi can do the job, too. It is easy to incorporate it into maven builds, which is not your case obviously, but might be of interest to others.

It can also check arbitrary sets of jars using its standalone mode.

查看更多
6楼-- · 2019-01-17 01:52

There is a tool by the name of Animal Sniffer that allows you to extract a signature for an API. Then it can statically verify that users of the API stick to the signature, and it can statically verify that implementors of the API have everything implemented. I think this would solve your problem nicely.

You can download the jar for Animal Sniffer from the codehaus maven repository: http://repository.codehaus.org/org/codehaus/mojo/animal-sniffer/

查看更多
姐就是有狂的资本
7楼-- · 2019-01-17 01:53

Do you need a to check a specific class or a generic tool for comparing jar's? If it's for 1 class, simply load the class in a custom class loader, check the methods signature by using reflection and that's it. If you need it for many JAR's/Classes this will be too much work.

查看更多
登录 后发表回答