Home > Articles > Programming > Java

  • Print
  • + Share This
From the author of

Introduction to Binary Compatibility

The exact rules for binary compatibility are spelled out in the Java Language Specification, Chapter 13. The exact rules are somewhat tedious to memorize, and I'll discuss them in detail in the next installment of this series. Here I'll just provide an introduction.

Let's start with an example. Two Java classes come from two different companies. Authorization is an authorization service provider; Hello is a user of that package:

package com.foocorp;

public class Authorization
{
  public Authorization()
  {
  }

  public boolean authorized(String userid)
  {
    return true;
  }
}
package com.technoco;

import com.foocorp.*;

class Hello
{
  public static void main(String a[])
  {
    Authorization auth = new Authorization();
    if(auth.authorized("me"))
      System.out.println("Hello, world");
    else
      System.out.println("You're not welcome.");
  }
}

When FooCorp releases version 2.0 of the Authorization class with new and improved authorization features, users of the Hello class would like to use that in their program without having to obtain a new version of Hello. The new version of Authorization is rather more complicated:

package com.foocorp;

public class Authorization
{
  public Authorization()
  {
  }

  public Token authorized(String userid, String password)
  {
    return null;
  }

  private boolean determineAuthorization(String userid, String password)
  {
    return true;
  }

  public boolean authorized(String userid)
  {
    return true;
  }

  public class Token
  {
  }
}

The developers at FooCorp have promised that the 2.0 version of Authorization is binary compatible with the 1.0 version (or, to put it another way, it does not break binary compatibility with version 1.0). It implements the same contract expected by Hello in the first place.

It's obvious that you could recompile Hello and have it be compatible with either version of Authorization; what may not be so obvious is that you don't have to recompile Hello. Even if you don't have Hello.java (and users of Hello aren't likely to, since most software publishers distribute only the binary, not the source), you can swap one version of Authorization.class for the other while keeping the same Hello.class.

This is not entirely novel to Java. UNIX systems have long used shared object libraries (.so files), and Windows systems have dynamic link libraries. You can swap out one library for another by replacing the file. Linking between names is done at runtime rather than at compile or link time, just as it is in Java. This gives some of the same advantages as Java binary compatibility: you can limit recompilation to a single library, and you can use it to patch part of a program. But Java introduced a number of improvements to the concept:

  • Java reduced the granularity from an entire library (perhaps hundreds of classes) to the individual class.

  • Java made it an everyday feature. Creation of shared libraries is generally done only rarely under C/C++. A program would have only a few libraries that could be shared, and you would have to consider carefully what you would make shareable and what would not be shareable.

  • Shared objects work only on function names. Java binary compatibility considers overloading, function signatures, and return types.

  • Java has better error checking. Version incompatibilities result in exceptions being thrown, which can be handled gracefully. Incompatible shared libraries in C/C++ result in crashes unless much extra effort is taken.

  • + Share This
  • 🔖 Save To Your Account