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.