Geographically-Distributed Development Tips and Tricks

Posted on Oct 27, 2011

 

distributed developmentDeveloping a shared code base around the globe presents many difficulties that are not faced in typical centralized development. Parasoft learned this first-hand over the past few years of developing a shared code base from multiple locations spread out over 3 continents.

These issues include:

  • Source control synchronization over slow networks.

  • Managing nightly builds and tests to coexist with continuous development between different time zones.

  • Enforcing common development practices through automation while protecting some level of freedom between groups.

  • Managing roles and responsibilities for shared code while under tight time constraints.

This series of blogs shares the lessons that Parasoft learned when tackling these issues—including how to best integrate multiple source control repositories and how use automation to establish a sustainable process.

Approach 1: Separate Source + Shared Binaries

The first approach towards integrating code from other development groups is to produce pre-packaged bundles of compiled code for each module. Each team will create a bundle for their own modules at stable points during development, and additional development will be done based upon the stable code bundles provided by other groups. Typically, these bundles will contain only compiled code, such as jar files in Java and dlls or static libraries in C++. The bundles may be uploaded to file servers or saved within a source control system as binary files. The final product will use modules from multiple groups together to create a complete application.

Pros

Creating code bundles for distribution is one of the easiest ways to integrate development efforts between teams. Most groups will already be set up to produce these distribution bundles for the release process. The same procedures used for public releases can be repeated at times of good code stability to create internal development releases. Errors introduced into an individual module will not affect other development groups as long as those errors are identified and resolved in time for that module’s next internal development release. Development groups can continue working without being inhibited by momentary errors in dependent modules.

Cons

Developing against pre-compiled bundles of code from other teams has some disadvantages. The main disadvantages of using pre-compiled code bundles are usage misunderstandings and uncertainty about the quality of integration.

There will inevitably be some confusion as code written by foreign developers is initially used by other groups. Naturally, some assumptions about the specification that seem intuitive to one group will be foreign concepts to another group.

Moreover, the differences in standard procedures for programming interfaces-- compounded with the lack of documentation about shared code and poor visibility of raw shared source code-- make integrating and understanding another group’s code contribution a daunting task. An understanding of shared code requires visibility into how that code is implemented and consistency with other programming practices within the organization.

A lengthy turn-around time is normal when something in one group’s module needs to change to accommodate another group. In the best case scenario, after a change request is made by one group, the next group can implement the change during working hours in their time zone, and the first group gets the change the next day. In the worst case scenario, one group waits far too long for the next stable internal bundle, or the change request is misinterpreted, causing further delays. Some changes to the source for one project might break a bundle depending on that project in such a way that would not be noticed unless that bundle were rebuilt or executed at runtime. Breaking changes need to be detected as soon as they are introduced, not later when another group tries to rebuild their own source or when the application runs in a production environment.

Sample Challenge

Consider the following Java code example:

public interface IShareable {
    String getComponentName ();
}

public class BusinessComponent implements IShareable {
    private static final String NAME = "Business Logic Module";
    public String getComponentName() {
        return NAME;
    }
...
}

Suppose interface IShareable and class BusinessComponent are developed by two different groups within the organization. Now suppose a developer for interface IShareable adds a new method String getComponentType() to the interface.

No compilation errors will be reported when rebuilding against a compiled jar containing BusinessComponent. Of course, if the development group responsible for class BusinessComponent rebuilds their source, they will notice a compilation error if they have a jar containing the latest IShareable on the classpath. However, the owner of IShareable might not know how many other groups are implementing the interface, and running older compiled implementation of that interface will work as long as the new getComponentType() method is not called. But if that method is called, it will throw a java.lang.AbstractMethodError exception unless both code sets are rebuilt against the latest versions of other code sets.

Making this Approach Work

Problems like this underscore the need for early detection at compile time or sooner, rather than seeing an exception if a certain code path is executed.

Some of the shortcomings of this approach can be addressed with small changes to the process:

  • A regularly scheduled nightly build and drop for each module will detect problems sooner and keep individual modules in sync with each other within one or two days.
  • Attaching source code to the compiled bundles for internal use will clear up some misunderstandings about code implementation and behavior.
  • Documentation levels for code, as well as programming patterns and runtime integration errors, can be monitored and enforced using automation.
Simple steps to improve the process will go a long way towards meeting shared code integration challenges.

Next week...Approach 2: Shared Source + Compile Everything

 

***

To explore additional resources on geographically-distributed development, visit our Geographically-Distributed Development Resource Center. Or, visit Parasoft's Geographically-Distributed Development page.

 

ctbook-cta.jpg