I would like to be able to compare two versions of a class / library to determine whether there have been any changes that might break code that calls it. For example consider some class Foo that has a method in version a:
public String readWidget(Object widget, Object helper);
and in version b the method becomes:
public String readWidget(Object widget); //removed unnecessary helper object
or something similar in the case of a field:
version a: public static Object sharedFoo;
version b: static Object sharedFoo; //moved to package private for version b
I would like a tool that will flag these changes as potential incompatibilities (but ideally not the reverse i.e. increasing the visibility of a method). Now I know that I can do this via reflections, or by analyzing the output from javap, however it seems like there should be an existing tool (preferably non-commercial). So I wanted to see if anyone can recommend something before I make the mistake of rolling my own / reinventing the wheel unnecessarily.
I might not be understanding the question, but isn't the compiler the exact tool that would solve this problem?
Re-compiling the classes that use Foo
against the new version of Foo
will illuminate very quickly if there are any incompatibilities.
Guava uses JDiff to report version changes, maybe you can find it useful, too?
Here's the answer you didn't want, but I think it's a valid answer:
The first problem with just recompiling all client code is that it might not be possible. The code might not belong to you; it might be custom code that one of your customers has written and is not available to you.
The second problem with just recompiling client code is that sometimes, you won't even get a compilation error because the calling code doesn't need to be changed. I ran into a problem like this once. I had an API method like this:
public void doSomething(){
}
with code that linked against it. I wanted to change it to this:
public boolean doSomething() {
}
So I did so and recompiled. There were no errors, because the code that called the first version of doSomething()
silently relinked to the new version (discarding the return value, which is valid in Java). Little did I know, however, that it did change the bytecode of the external class when I recompiled. We started to get errors where the API was updated but the code using it wasn't recompiled.
So instead of looking for errors, I should have also been looking at which external files had their bytecode changed as a result. At that point, I'd say you should just be using unit tests for this purpose since you should be writing them anyhow.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With