Summary
Introduce the notion of family and criterion to remove the static dependencies that exist between feature-packs.
Problem
Today, when developing feature-packs that depend on WildFly feature-packs, we are bound to use exact instances (mainly identified by Maven Coordinates) of feature-packs.
At provisioning time, the same dependencies must be present in the provisioning configuration (with possible different versions).
This is not flexible, the same feature-pack can’t depend on a set of feature-packs that would offer the same functionalities. You need to define multiple feature-packs (even if they are identical) just to handle the dependencies.
That doesn’t scale. In particular in a context where we would like to see WildFly support multiple versions of a specification (e.g.: Jakarta EE 10 and Jakarta EE 11). We should be able to say that we want WildFly with EE10 in one provisioning configuration and WildFly with EE11 in another provisioning configuration. WIldFly feature-pack should be the same and not bound to a specific dependency. This applies also to other feature-packs (datasources, cloud, …) that should work, if applicable, with any combinations.
Another example that highlights the problem is defining a feature-pack that would apply indifferently to WildFly core feature-pack (used in test suite), WIldFly EE, WildFly and WildFly Preview. The “Deployment transformer" use case (a feature-pack that would provision what is needed to transform in a custom way some deployments). This feature-pack doesn’t care about the specific feature-pack it is provisioned with. It just needs that the WildFly deployment server feature be present.
Family and Criteria
This notion of server feature is key. A feature-pack should express the set of server features it is implementing. Other feature-packs should be able to express that they depend on a feature-pack that provides a set of server features (criteria).
Let’s group all the feature-packs that WildFly defines in the “wildly” family. Each feature-pack becomes a member of this family. The members of a family are exposing criteria (the server features) that can be unique to a member or shared by multiple members. In addition, members can inherit from other members, so some criteria can be implemented locally or inherited.
WildFly family criteria
An example of criteria (that should be enough to help understand this new feature) we can find today in the wildly family (non-exhaustive):
* `deployment`: ability to deploy an application
* `jakarta-ee`: An implementation of the Jakarta EE spec
* `jakarta-ee10`: A specific implementation of the Jakarta EE version 10
* `microprofile`: An implementation of the MicroProfile spec
* `microprofile-7.1`: A specific implementation of the MicroProfile spec version 7.1.
* `jakarta-ee11`: A specific implementation of the Jakarta EE version 11
Let’s dispatch the criteria in each WildFly feature-pack:
* WildFly core feature-pack: deployment
* WildFly ee feature-pack: deployment, jakarta-ee, jakarta-ee10
* WildFly feature-pack: microprofile, microprofile-7.1
* WildFly preview feature-pack: deployment, jakarta-ee, jakarta-ee11, microprofile, microprofile-7.1
Now let's handle the inheritance that exists today between some feature-packs.
WildFly feature-pack depends on WildFly ee feature-pack. From the list of examples criteria, it depends on this feature-pack to use: `jakarta-ee` and ` deployment`. So, the dependency on WildFly ee should be limited to such criteria.
Inheritance makes parent criteria on which a child depend to be also exposed by the child (as inherited but that is an implementation detail). So, the criteria exposed by each feature-pack becomes, after inheritance:
* WildFly core feature-pack: deployment
* WildFly ee feature-pack: deployment, jakarta-ee, jakarta-ee10
* WildFly feature-pack: microprofile, microprofile-7.1, deployment, jakarta-ee
* WildFly preview feature-pack: deployment, jakarta-ee, jakarta-ee11, microprofile, microprofile-7.1
Flexible dependency and provisioning
Now that we have our feature-pack exposing criteria, we can define feature-packs that depend on the feature-packs of the WildFly family:
The WildFly datasources feature-pack (that adds datasources and JDBC drivers) requires `jakarta-ee` from the `wildfly` family.
The WildFly cloud feature-pack (that configure a complete wildly for the cloud) requires `jakarta-ee` and `microprofile` from the `wildfly` family.
The WildFly transformer feature-pack requires `deployment` from the `wildfly` family.
With that in place, we can now mix the feature-packs. At provisioning time resolution of family and criteria allows to identify the actual dependencies in use and to bind to:
(WildFly || WildFly EE || WildFly Preview) + WildFly datasources feature-pack
(WildFly || WildFly Preview) + WildFly cloud feature-pack
(WildFly || WildFly EE || WildFly Core || WildFly Preview) + WildFly transformer feature-pack
NOTE: One benefit is that we can, at provisioning time, check that at most one member is bringing a given criterion. If we have 2 members that implement locally (not via inheritance) a criterion, it means that we have a duplicate and a member needs to be removed (e.g.: explicit provisioning of WildFly core + WildFly EE or WildFly Preview + WildFly EE should be detected and aborted, today an unexpected state is created, hard to debug).
Advanced example with hypothetical support for Jakarta EE 11
For version X of WildFly, Jakarta EE 11 should become the default implementation. A new feature-pack for Jakarta EE 10 could be defined allowing to keep using WildFly with Jakarta EE 10 for some time. WildFly Preview would start to support Jakarta EE 12 (I am not modifying the microprofile version there although I suspect that it would change).
New criteria that appear (and none would been removed, but we can expect some criteria to be removed for new WildFly releases):
The new set of feature-packs and mapping of criteria:
* WildFly core feature-pack: deployment
* WildFly ee feature-pack: deployment, jakarta-ee, jakarta-ee11
* WildFly ee 10 feature-pack: deployment, jakarta-ee, jakarta-ee10
* WildFly feature-pack: microprofile, microprofile-7.1
* WildFly preview feature-pack: deployment, jakarta-ee, jakarta-ee12, microprofile, microprofile-7.1
We can see that both WildFly ee feature-pack and WildFly ee 10 feature-pack share the jakarta-ee criterion that is all that WildFly needs. So, one of the two feature-packs can be provisioned with WildFly feature-pack (same applies to other feature-packs).
NOTE: WildFly feature-pack would possibly need other criteria to limit to a minimum version of Jakarta EE specification (e.g.: minimum EE 10). Such criterion could be implemented by the two WildFly EE feature-packs and become an expected criterion for the dependency.
Conclusion
Provisioning time would become flexible with less feature-packs defined. It would allow to leverage feature-pack functionalities in different context. In this first step we can see criteria as “labels”, trusting the feature-pack developer that the criteria are actually full-filled. In the future this could be constrained by introducing formal feature-pack spec (or exposed API) that would capture what a criterion should contain (Galleon layers, Galleon packages, Galleon features).
This feature would be backward compatible at provisioning time. The family/criteria notion would be handled internally and not exposed.
It would impact Galleon, WildFly Galleon Plugins and all the other feature-packs that depend on WildFly.
That is food for thought for now, in a near future I plan to create JIRAs and a WildFly proposal for it.
Feedback welcome.
Thank-you.
JF Denise