Question about versioning strategy and approach for V3

195 views
Skip to first unread message

kyl...@gmail.com

unread,
Aug 6, 2020, 1:16:50 AM8/6/20
to AEM Core Components Developer Community
Hello,

Most of the projects I work on are for single clients, where things like backwards compatibility aren't really a major concern.

However, I recognize that this is not the case for a project like this; this is probably especially true for those using AEM as SaaS.

Looking at the current code, It is not readily apparent to me how non-backwards compatible changes will be made in the future?

While there are, in some cases, V1 and V2 components; they share the same interfaces, which are not versioned in a similar way. What happens when there is some major change that would require changing the interface? 

According to the principles of semantic versioning, that would necessitate a major version bump (e.g. 3.x.x).

Will 3.x.x be designed to run in tandem with 2.x.x?
Will 3.x.x (or 10.x.x) attempt to maintain BC with 2.x.x?

Can someone from the core team please elaborate on how this is going to work when breaking changes are introduced?

Thanks,
Kyle

Vlad Băilescu

unread,
Aug 7, 2020, 10:28:11 AM8/7/20
to AEM Core Components Developer Community, ra...@cotescu.com
Hi Kyle,

Our main design goal, related to backwards compatibility, was that any customer would be able to update to the latest Core Components version without breaking their implementation. In order to do that we added the following restrictions:

- Sling Model interfaces will not remove methods, just add. When adding methods, a default implementation would be provided (usually throwing UnsupportedOperationException to highlight that the method needs to be implemented). This will allow updating the Core Components bundle without requiring a recompilation of the customer's dependent bundles.
- Core Components resource types are versioned (ie: ../page/v1/page and ../page/v2/page). For convenience we recommend using thin proxy (components having a supertype to a specific version of the corresponding core component), so that site-wide component version upgrade is simpler. This protects customer implementation from breaking markup changes.

This approach has some gotchas:
- People have complained about not making the Sling Models implementation public, thus making it hard to extend, even with https://github.com/adobe/aem-core-wcm-components/wiki/Delegation-Pattern-for-Sling-Models
- We have been, on occasion, not very diligent with tracking markup changes, which resulted in problems for some customers. We try to learn from our mistakes and generally capture our rules at https://github.com/adobe/aem-core-wcm-components/wiki/versioning-policies

To answer your questions:

1. Core Components are designed so that you will always use the latest available version.
2. Breaking changes usually lead to new component versions and, possibly, new Sling Models implementations. Old component versions would still be available (for a while at least) side-by-side.
3. We generally consider a major version release whenever we add a whole bunch of components or update the markup of many of the components (by creating new versions).

Hope this helps,
Vlad


--
You received this message because you are subscribed to the Google Groups "AEM Core Components Developer Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to aem-core-componen...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/aem-core-components-dev/532cd597-9368-477b-907f-d1c8cca3cdf0n%40googlegroups.com.

kyl...@gmail.com

unread,
Aug 19, 2020, 12:28:38 AM8/19/20
to AEM Core Components Developer Community
Hello,

Thank you, for the response.
My thoughts were more along the line of changing the Interfaces, not just addinging methods to existing interfaces and adding a V2,3,...,N  model implementation and component.

I will give an example of a change that might be beneficial.
The List interface currently defines the following method, the Container interface also defines a nearly identical method.
```
@NotNull
default Collection<ListItem> getListItems() {
    throw new UnsupportedOperationException();
}
```

All well and good,  but if the generic type of the returned collection were something like 
```
@NotNull
default Collection<? extends ListItem> getListItems() {
    throw new UnsupportedOperationException();
}
```
Then interfaces that extend the List interface could be free to return specific types of list items.
If the model is invoked using "List" class, then all you know is that the list items satisfy the condition of being ListItems.
If the model is invoked using a model for an interface that extends "List", then you may know that the items are a specific type of ListItem.

This type of change, even if only the interface was changed and no implementations were modified, is a breaking change that will never be backwards compatible.
If the members that are exported from the bundle can only ever be added to, but never have anything removed (deprecated, sure, but not removed), and can never be refactored or rearchetected to suite the evolving needs and growing scope of the project then I fear the project will become locked into legacy decisions that may no longer suit the needs.

I see that there are references to a version 3.0.0 in the GitHub project. 
For this version are major API breaking changes allowed, as semantic versioning would imply?

Kyle

Vlad Băilescu

unread,
Aug 25, 2020, 11:44:43 AM8/25/20
to AEM Core Components Developer Community
Hi,

As I mentioned in my previous email, we try to structure all changes so that AEM users do not need to recompile their bundles or update their HTL overlays.

For your given example, that will never fly. Best we could do is deprecate the existing method and provide an alternate one with the updated return type.

For 3.0.0 the highlight will be the changes that Stefan did in regards to link handling (https://github.com/adobe/aem-core-wcm-components/issues/713)

On the longer term, it was suggested that it's perhaps better to switch from the current model (one interface with different implementations for different component versions) and instead move to versioned Sling Models and exposing implementations as well (so that they can be easier extended), eg: v1.List, v2.List, v3.List. We're reluctant to accept this as the best solution since it will be a mess to keep the referenced versions properly synced.

Best,
Vlad

Reply all
Reply to author
Forward
0 new messages