How to identify a missing method (Binary Compatibility) in a JAR statically

binary-compatibility, bytecode, jar, java, static-analysis

Solution

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

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

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

Problem

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.

Original source

Related problems