Git Product home page Git Product logo

Comments (10)

siom79 avatar siom79 commented on May 18, 2024 1

With version 0.7.0 japicmp now supports source compatibilty changes.

from japicmp.

robinst avatar robinst commented on May 18, 2024

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.

from japicmp.

bondolo avatar bondolo commented on May 18, 2024

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.

from japicmp.

siom79 avatar siom79 commented on May 18, 2024

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.

from japicmp.

robinst avatar robinst commented on May 18, 2024

@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 java.lang.AbstractMethodError for implementations that do not implement the new method.

So, in practice, ignoring this may lead to errors at runtime.

This means I can not rely on breakBuildOnBinaryIncompatibleModifications. What I do for now is use breakBuildOnModifications, and manually check for source compatibility. When it is compatible, I'll have to add an exclude for the newly-added method.

from japicmp.

siom79 avatar siom79 commented on May 18, 2024

@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 breakBuildOnBinaryIncompatibleModifications option should only check if you can run the new version of your library with applications that have been compiled against the old version. For example, your application is compiled against Google's guava in version 16.0 and now you upgrade to 16.0.1. If in 16.0.1 a new method has been added to an interface, then your application should run without any modifications.

from japicmp.

robinst avatar robinst commented on May 18, 2024

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 walkFileTree. Java then calls the appropriate methods of the interface.

Now, let's say Java adds a new method foo to the FileVisitor interface and calls it in walkFileTree. This would pass the check. But clients that upgrade to the new Java version would now fail at runtime.

So even though the change is binary compatible, compatibility as you define it is broken:

The breakBuildOnBinaryIncompatibleModifications option should only check if you can run the new version of your library with applications that have been compiled against the old version

from japicmp.

siom79 avatar siom79 commented on May 18, 2024

Thank you for pointing me to the exact problem. Now I can reconstruct the java.lang.AbstractMethodError.

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 java.lang.AbstractMethodError is actually thrown in the library code.

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?

  • Adding source compatiblity as a new feature is hard, as it is not easy to determine, particularly in the case of wildcard imports (see this blog article written by a JDK engineer).
  • Scanning the library under investigation for invocations of the new method through an interface could help to solve your particular problem, but might not be a general solution.
  • Just making the addition of a method to an interface a binary incompatible change would not be aligned with the Java Language Specification.

Do you have an opinion on that?

from japicmp.

robinst avatar robinst commented on May 18, 2024

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 @noimplement in Javadoc.)

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".

from japicmp.

robinst avatar robinst commented on May 18, 2024

👍 Nice work, thanks!

from japicmp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.