-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding a method to an interface should be incompatible modification #59
Comments
Let me clarify a bit. It does indeed not break binary compatibility as defined by the JLS. But it does break source compatibility if the clients are expected to implement the interface (say for a callback). I guess what I'm after is a way to break the build if source compatibility is broken. |
This will apply only to class file version 51 and earlier as Java 8 safely allows additions to interfaces if a default implementation is provided. |
Indeed, adding a method to an interface does not break binary compatibility. In theory this is described here in the Java Lang. Specification. And in practice it does really work. Having at runtime a new version of the interface with a new method does still executed the old code, although the class does not implement all methods from the new interface. Source code compatibility is currently not supported. |
@siom79: Calling the methods that the class already implemented is not a problem, correct. But if the new method is called, it will fail at runtime with an So, in practice, ignoring this may lead to errors at runtime. This means I can not rely on |
@robinst: OK, but if you are calling the new method of the interface, then you have already upgraded to the new version, don't you? Or how does the client code know about the new method in the interface? The |
I'm sorry, I should have been more clear with my example. Let's take a real-world example: Java 7 has a FileVisitor interface. It is used as a parameter for Files.walkFileTree. Users of this API are expected to implement this interface and pass it as an argument to Now, let's say Java adds a new method So even though the change is binary compatible, compatibility as you define it is broken:
|
Thank you for pointing me to the exact problem. Now I can reconstruct the But this problem is hard to solve in a general form. The point is that in the case of the visitor pattern, the library under development itself calls the new method. The application compiled against an older version of this library still does not know about this new method. The exception On the other hand, binary compatibility in the sense of the Java Language Specification is still not broken. What could be a solution to the problem?
Do you have an opinion on that? |
I think what would be useful is if interfaces could be marked as "to be implemented by clients" (e.g. like FileVisitor) as opposed to being implemented by the library itself. (In the Eclipse code base, the opposite is done, interfaces that should not be implemented by clients are marked as Then, if an interface is marked as that, adding a new method breaks compatibility. If the interface is not marked, then adding a new method is fine (other modifications such as deleting an existing method is still a break though). It could be done in a similar fashion to includes/excludes. Not sure how such a section should be named, maybe "implementedByClients" or something more specific, "breakOnAbstractAdditions". |
With version 0.7.0 japicmp now supports source compatibilty changes. |
👍 Nice work, thanks! |
breakBuildOnBinaryIncompatibleModifications
set totrue
Expected: It should fail
Actual: It doesn't fail
Adding a new method (without default implementation) to an interface breaks compatibility, because existing implementations will break. See Eclipse's reference for this too. Or am I missing some configuration for this?
The text was updated successfully, but these errors were encountered: