Semantic Versioning IMHO mostly cares about Consumers (which are many bundles) as Providers usually need to be changed for any kind of API change and are only a few bundles compared to the many consumer bundles. So yes, although changing a consumer interface requires recompilation of the provider bundle that is usually desired (especially if the class is closely related to a provider type class in the same package).
So I guess the best practice is rather: - Put closely related classes in the same package - Don't let the package contain too many classes (because obviously the fewer classes share one package version the less of a risk for unnecessary recompilation of consumers) Konrad > On 30. Jun 2021, at 06:54, Carsten Ziegeler <[email protected]> wrote: > > You can regard provider type as the implementor of the api of a package > whereas everything marked as consumer type is implemented by users of that > api. > > So yes, if you make any changes to that package, add a new interface, add a > new method etc., you need to adjust the implementor. > > For example, if you add a new consumer interface, it will break the > implementor - but it is highly likely that the implementor needs to do > something with that new interface, like picking up all services implementing > that new interface and eventually invoking those. So it is natural that the > implementation needs to be updated. > > Of course, if the change is about static utility code, then yes this is not > breaking the implementor. But I consider this an edge case. > > You can't make changes to a consumer type (unless you add a default method to > an interface) as this will break all clients. > > So again, many use cases for putting consumer and provider type interfaces > into a single package are totally valid and good api style. > > Moving api artifically into separate packages just because of the fear that > changes require to update the implementation, can create a bad api experience. > > Side note, if you have api and the implementor in the same module, the whole > discussion goes away. Which is another fun discussion :) > > Regards > Carsten > > > Am 29.06.2021 um 22:48 schrieb Eric Norman: >> Hi Konrad, >> Can you confirm that mixing your 3rd scenario (as below) with any of the >> other 3 within the same bundle also results in the narrow version range for >> that imported package? >> @ProviderType 1.1.0 yes >> [1.1, 1.2) Provider >> The point being that as soon as you implement any ProviderType interface in >> your bundle then you can't add new (unrelated?) classes to that exported >> package or change any ConsumerType classes in that exported package because >> those changes would result in a bump of the exported minor version number. >> The imported package range for any bundles that were built against the >> previous release would no longer match the narrow version range exported by >> the new release. >> This is the scenario that was discussed with SLING-10031 >> On Tue, Jun 29, 2021 at 12:28 PM Konrad Windszus <[email protected]> wrote: >>> Hi, sorry for the confusion here, I think I may be just wrong. >>> >>> From the standard policies from Bnd I do no longer think mixing Consumer >>> and Provider in one package can lead to breaking users of the API more >>> easily. >>> >>> Let's quickly recall what the rules are: >>> >>> Rules for Exported Versions >>> ==== >>> >>> ConsumerType >>> Every binary incompatible change requires an increment on the major >>> version. >>> >>> ProviderType >>> Every binary incompatible change requires (at least) an increment on the >>> minor version. >>> >>> Rules for Imported Versions >>> ===== >>> >>> For each interface/ non final class it is stated, whether it is supported >>> to be implemented/extended by Consumers (and providers, the default) or by >>> Providers only. That information together with the information whether the >>> interface is just used or really implemented determines the version-range >>> of the import-package statement: >>> >>> Annotation on class/interface | Version Implemented | Import-Package >>> Version Range | Versioning Policy >>> @ConsumerType 1.1.0 yes >>> [1.1, 2.0) Consumer >>> @ConsumerType 1.1.0 no >>> [1.1, 2.0) Consumer >>> @ProviderType 1.1.0 yes >>> [1.1, 1.2) Provider >>> @ProviderType 1.1.0 no >>> [1.1, 2.0) Consumer >>> >>> Those policies can be overwritten via the instruction >>> http://bnd.bndtools.org/instructions/consumer_policy.html and >>> http://bnd.bndtools.org/instructions/provider_policy.html. >>> From those rules I cannot construct a usage which would point at splitting >>> Consumer and Provider types. >>> >>> I think my confusion initially came from >>> https://github.com/apache/felix-dev/blob/057bb85d7d496671755cd53cffc9e91a17c1d17c/tools/osgicheck-maven-plugin/src/main/java/org/apache/felix/maven/osgicheck/impl/checks/ConsumerProviderTypeCheck.java#L115 >>> @Carsten: Do you remember why that usage leads to an error in >>> osgicheck-maven-plugin? >>> >>> Konrad >>> >>> >>> >>>> On 29. Jun 2021, at 20:23, Eric Norman <[email protected]> wrote: >>>> >>>> I haven't looked at this too closely, but do you think that there could >>> be >>>> some benefit to keeping them in separate packages if you expect the >>>> consumer and provider apis to evolve at a different pace? >>>> >>>> If I recall correctly, the bundles that import and use stuff from a >>> package >>>> that contains both consumer and provider classes may get a too specific >>>> range for the import package range. >>>> This has to do with bndlib choosing the "provider-policy" instead of the >>>> "consumer-policy" when calculating the version ranges. >>>> >>>> From what I read, the default definitions for bnd are: >>>> >>>> -consumer-policy ${range;[==,+)} >>>> -provider-policy ${range;[==,=+)} >>>> >>>> >>>> >>>> Specifically, the import-package item can end up with a narrow range as >>>> something like org.apache.sling.whatever; version="[2.4, 2.5)" for the >>>> importing bundles which can leads to troubles when the next minor change >>>> requires the exported package to get bumped to "2.5.0" since that >>> exported >>>> package number no longer satisfies the import package range. This would >>>> mean that all the "importing" bundles would have to change as well and >>> you >>>> end up with a cascade of new releases just for some minor change in the >>>> "consumer" part of the exported package even if the changes were trivial >>>> and backward compatible. >>>> >>>> Regards, >>>> -Eric >>>> >>>> >>>> >>>> On Tue, Jun 29, 2021 at 8:54 AM Carsten Ziegeler <[email protected]> >>>> wrote: >>>> >>>>> I don't think that not mixing consumer and provider interfaces is a best >>>>> practice. >>>>> >>>>> The OSGi specs - which I think are usually following best practices - >>>>> are mixing them. For example event admin where the event admin interface >>>>> is in the same package as the event handler. >>>>> >>>>> The markers actually help putting those interfaces into the same >>>>> package. In above example you can change the event admin interface >>>>> without breaking the event handler. >>>>> >>>>> The framework api does the same, confgig admin etc. >>>>> >>>>> It's good to split packages based on purpose and usage. For example to >>>>> move SPI interfaces into a separate package. >>>>> >>>>> Regards >>>>> Carsten >>>>> >>>>> Am 29.06.2021 um 16:49 schrieb Bertrand Delacretaz: >>>>>> Hi Konrad, >>>>>> >>>>>> On Tue, Jun 29, 2021 at 3:04 PM Konrad Windszus <[email protected]> >>> wrote: >>>>>>> - Please don't mix Consumer and Provider interfaces in the same >>> package >>>>>>> ( >>>>> >>> https://github.com/apache/sling-org-apache-sling-sitemap/tree/master/src/main/java/org/apache/sling/sitemap/generator >>>>>>> and >>>>>>> >>>>> >>> https://github.com/apache/sling-org-apache-sling-sitemap/tree/master/src/main/java/org/apache/sling/sitemap/builder/extensions >>>>> ) >>>>>>> as that enforces updates to break more consumers than necessary.... >>>>>> >>>>>> Could you elaborate on that? The issue is not obvious to me. >>>>>> >>>>>> More generally, I think it would be useful for us to document best >>>>>> practices around Consumer and Provider interfaces. >>>>>> >>>>>> If someone has links to such best practices that would be great, >>>>>> otherwise feel free to add some notes in response to this message and >>>>>> I'll write something up for https://sling.apache.org/ >>>>>> >>>>>> -Bertrand >>>>>> >>>>> >>>>> -- >>>>> -- >>>>> Carsten Ziegeler >>>>> Adobe Research Switzerland >>>>> [email protected] >>>>> >>> >>> > > -- > -- > Carsten Ziegeler > Adobe Research Switzerland > [email protected]
