Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - binary compatibility of abstract class & subclasses

In Java, I define an abstract class with both concrete and abstract methods in it, and it has to be subclassed independently by third-party developers. Just to be sure: are there any changes I could make to the abstract class that are source compatible with their classes but not binary compatible? In other words: after they have compiled their subclasses, could I change the abstract class - apart from e.g. adding an abstract method to it or removing a protected method from it that is called by subclasses, which are of course source incompatible - in a way that could force them to recompile their subclasses?

like image 481
thSoft Avatar asked May 14 '10 22:05

thSoft


People also ask

How do I know if Java is binary compatible?

Java API Compliance Checker (JAPICC) is a tool for checking backward binary and source-level compatibility of a Java library API. The tool checks classes declarations of old and new versions and analyzes changes that may break compatibility: removed methods, removed class fields, added abstract methods, etc.

What is binary compatibility in Java?

Binary compatibility is an old idea that involves both hardware and software. Two computers can be considered binary compatible if they can run the same software without requiring that the application be recompiled.

What is the binary name of class in Java?

For example, the normal binary name of class Thread is java. lang. Thread . In the internal form used in descriptors in the class file format, a reference to the name of class Thread is implemented using a CONSTANT_Utf8_info structure representing the string java/lang/Thread .

WHAT IS interface in Java with example?

An interface in Java is a blueprint of a class. A Java interface contains static constants and abstract methods. The interface in Java is a mechanism to achieve abstraction. There can be only abstract methods in the Java interface, not the method body. It is used to achieve abstraction and multiple inheritance in Java.


2 Answers

If it isn't too late to change your system, I would suggest that you do that. Overriding is usually not a good way to customize functionality, as it is incredibly fragile. For example, if you later use a method name that your clients have used (which they are now unintentionally automatically overriding), then it is possible that the override will completely break the invariants of your class. A usually better way of providing customization is to give your clients an interface which is limited to just the customized behavior, and then you have a fully concrete class that depends on an instance of this interface, and delegates appropriately to the interface when it needs to use the customized behaviors. This way, your code and your client's code are completely separated, and they won't interfere with each other.

like image 142
Michael Aaron Safyan Avatar answered Oct 03 '22 02:10

Michael Aaron Safyan


I am assuming that you are using "binary incompatibility" in the technical sense; e.g. where the classloader detects the incompatibility and refuses to load the classes.

Binary incompatibility could also be introduced if you added a visible method and declared it final, and that method collided with the signature of some existing method in a third-party subclass. However, if the method is non-final, the existing method will turn into an override of your (new) method which might cause problems ... but not binary incompatibility.

Likewise, adding new visible fields will result in hiding, may result in confusing behavior and will break object serialization. But this will not result in binary incompatibility.

In general this points to the fact that you need to consider application semantic issues as well as simple binary compatibility. And the Java type system won't help you there.

For completeness, there are a other things that you could do in your code that would break binary compatibility for the 3rd party classes:

  • reduce the visibility of your abstract class and/or its methods,
  • change the signatures of other classes used as parameter result and exception types,
  • change the chain of superclasses that your abstract class extends, or make an incompatible change in those classes, or
  • change the tree of interfaces that your abstract class implements, or make an incompatible change in those interfaces.
like image 31
Stephen C Avatar answered Oct 03 '22 04:10

Stephen C