Binary compatibility issue - an example?

649 views Asked by At

As far as I understand the source compatibility and how you can easily show an example that would break source compatibility (change name of the method, remove method etc.), I am having a bit of a problem seeing how binary compatibility can be broken in practice. Does anyone have a simple example of preservation of source compatibility that would cause binary compatibility issues i.e. no code changes are required but recompilation is necesssary?

4

There are 4 answers

0
Jon Skeet On

One example (and this is by no means the only one) would be if the signature of a method in a library changes, in a compatible way. For example, consider:

// Library.java v1
public class Library {
    public static void print(String foo) {
        System.out.println(foo);
    }
}

// Client.java v1
public class Client {
    public static void main(String[] args) {
        Library.print("hello");
    }
}

Compile and run:

$ javac Client.java Library.java
$ java Client
hello

Now change Library.java - note the type of the foo parameter:

// Library.java v2
public class Library {
    public static void print(Object foo) {
        System.out.println(foo);
    }
}

Just recompile Library.java and try to rerun Client:

$ javac Library.java 
$ java Client
Exception in thread "main" java.lang.NoSuchMethodError: Library.print(Ljava/lang/String;)V
    at Client.main(Client.java:3)
0
Joop Eggen On

If you import an interface with string constants. (An anti-pattern in Java.)

Then the importing class copies the constants in the constant table, and uses those constants immediately. The import dependency to the interface then is missing.

When the string value of the constant in the interface is changed, the compiler does not see that it needs to recompile the class that will remain using the old value - as there is no longer an import to the interface.

The running is not broken, but the behaviour is - wrong value.

0
Ekans On

An example I met :

public class Class1 {
   public void do() {
      System.out.println("do!");
   }
}

Client part :

public class Class2 {
   public void callDo() {
      Class1 c = new Class1();
      c.do();
   }
}

Now you change the return of do method :

public class Class1 {
   public String do() {
      System.out.println("do!");
      return "done!";
   }
}

If you run the client code without a recompilation you will get a NoSuchMethodError exception because the method signature has changed.

0
praitheesh On

First need to understand both compatibility.


Source compatibility - Program is source compatible with new version if Program can be compiled with that new version of code(library or api)
Binary compatibility - Program is binary compatible with new version of code if Program can be linked with that code without recompilation

Following link has more example for "Source compatible but Binary incompatible "

  1. Specialising Return Types

enter image description here

  1. Generalising Parameter Types enter image description here
  2. Primitive vs Wrapper Types enter image description here


Read http://praitheesh.blogspot.com.au/2014/09/compatibility-and-api-evolution-in-java.html for more details.