Michaël is an IT engineer who graduated in image processing. He worked in per grammar code generation before joining Tocea's R&D team. He now participates to the development of new tools and algorithm for real-time code analysis, control and enhancement. Michaël has posted 1 posts at DZone. You can read more from them at their website. View Full User Profile

How to identify upcoming regressions or API breaks

09.18.2012
| 2083 views |
  • submit to reddit

What is a regression ?

Regressions are due to a change in the code or its dependencies, but sometimes also to environment changes. We won't be talking about this last point in this post.

There are two types of regressions: compile-time and run-time. On one hand compile-time regressions make your code not compliant anymore for your compiler, script interpreter, etc. On the other hand run-time regressions, the tricky ones, cause code crashes, bugs, or strange behavior wherever it was working before.

How can I get regressions in my code ?

Here we are interested in Object Oriented programming, but other languages without the notion of class or inheritance face the same hurdles with function and method definitions. There are many ways you can get regressions within your own code and much more when you have library dependencies. This is because when a dependency gets updated it may bring any of the following regressions without you knowing it.   


Change Regression
Compile-time Method signature modified/removed Code using this method will not be compliant anymore
Interface/abstract Class inheritance removed Implementing classes loose a behaviour and can no more be cast in the supertype
Interface/abstract Class inheritance added Compiler will ask for an implementation of the abstract/signature methods
Run-time Method implementation modified Unpredictable behaviour
Run-time loaded code with a different API version (RMI, Spring, etc) If APIs are not compliant the code will crash for any of the previous reason
 

I'll give an example, let's say class Foo implements the Bar interface

public interface Bar
{
    // Cool signatures inside
}

public class Foo implements Bar
{

    private UnserializableType boo;

    Foo(UnserializableType boo) {

        this.boo = boo;// Nothing to do with DBZ

    }

    // Cool methods implementations doing stuff with boo 

}

Everything seems fine until this happens!

public interface Bar extends Serializable
{
    // Still cool signatures inside
}

The interface become Serializable but my implementation can't be properly serialized because of the boo field that is not serializable itself. Hence the run-time regression! This case of interfaces extending a new type is special because the Serialization interface has no method constraint yet to add a behavior for Java. But there will be a compile-time regression for any new method added to an interface.

Can something help me identify the regressions before they happen ?

Some regressions are nearly impossible to predict, however for most of them you can at least have a hint on where to check for regressions. Of course compile-time regressions can be identified easily compared to run-time ones. In the case your working only with your own code in a single project then compile-time regressions are often identified by your IDE single-handed (Eclipse, Netbeans, Visual Studio, etc). And because of your situation you're allowed to do such and just ctrl+Z to get everything back in order.

However if you're working with multiple dependencies then it's another game. You're not aware of regression while updating a dependency let's say from a version 1.2 to a newer. Is the 1.3 or 1.4 compliant? both? You'll have to check manually by changing the dependency then compile your code. It is not really funny nor sexy. And when it gets to run-time regressions then you'll have to go for all your test chain again. So now here are the ways to predict regression before they happen !

  • Compare the signatures of different API versions: Are some methods or fields modified? Inheritance broken? Created? It's actually really feasible especially in Java thanks to the Reflection API
  • Detect the implementation changes: It is not necessary to have the source code changes but only a hint on if the bytecode/compiled code changed for this method. Then you'll have a hint on where to check for regression without having to profile all your code.
  • Identify the use of the API in your code: Are the changes going to affect you code? Or are you not using this part?

Tools & Links

What's Next ?

Version compliance between APIs is a very important matter and is source of number of testing and regression overloads. Hence our company is interested by putting this checking process with no burden in the everyday programmer life. Tocea is coming with an open-source compliance checking maven plugin that can be integrated in a code analysis tool chain. Stay tuned.

Published at DZone with permission of its author, Michaël Picovschi.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)