For 4.Next we could maybe look at going with a good enough approach of using the service provider to load an implementation peer for each API class.
There's been ongoing debate indeed of using CDI at that level, or to completely redesign the API while at it, etc etc. Of course those things are Ultimately Better, but they never happen.
As an example, UIComponentBase:
public abstract class UIComponentBase extends UIComponent {
private final UIComponentBasePeer peer = ServiceLoader.get(...);
@Override
public Map<String, Object> getPassThroughAttributes(boolean create) {
return peer.getPassThroughAttributes(create);
}
@Override public String getClientId(FacesContext context) {
return peer.getClientId(context);
}
@Override public String getId() { return peer.getId(); }
// etc
}
There's obviously a few things to decide here, for instance what's the best type for "UIComponentBasePeer", but in broad lines something like the above may be the most practical way to get this effort at least started.
Given that The Best solution has been years in the making with
little to show for it, is there something Good Enough we can do in
the short term? I'd love to be able clean the build up, separating
API from impl classes as much as we can. So far, I've experimented
with two approaches: 1) Restructure the source tree, or 2) Add a
profile (as shown below) to produce a "stripped" jar.
Reorganizing the code seems to be doable, but there's a fair bit
of code shared between impl and API that will need to be removed,
duplicated, or moved to another module. That last option would
add, potentially, an api/ and (say) shared/ modules, increasing
the number of artifacts to deploy, etc. I'm not sure that's a real
big deal, as transitive deps should make that pretty transparent.
Just (maybe) a bit more work at release time (based on my
experience publishing jars, it should be mostly transparent).
Adding the extra profile minimizes changes to the repo, but would
require more work in the CI and deploy/publish setup, which may
not be desirable.
Personally, I prefer the reorg approach, as I think it would
produce a cleaner build, and, perhaps, inch us closer to The Best
solution that has eluded greater minds than I over the years. :)
Does anybody have a preference or further thoughts? I can produce
PRs for each approach to compare and contrast, if that would help.
On 6/8/22 4:53 PM, arjan tijms wrote:
Hi,
Partially the Faces API build is already doing something
quite like this.
I got to discussing this with some other WildFly
engineers, and Farah (thanks! :) suggested just using a
separate profile. That would leave the code base as it
(there's a fair bit of util code shared between impl and
API class, which doesn't feel right to me, fwiw), and
require only a simple build change, which would look a lot
like this:
Thoughts on either approach? I can go either way, so I
hope at least one is acceptable. :)
On 6/8/22 6:37 AM, Jason Lee wrote:
Currently for WildFly, we maintain a fork of the
Mojarra code base. There are some historical reasons for
that that are no longer relevant, so I'd like to
transition us to using the upstream Mojarra artifacts
directly. One of things we do as part of our build and
packaging step, though, is to exclude the API classes
(javax.*/jakarta.*), which we include via
jakarta.faces:jakarta.faces-api. As things stand now, we
will need to continue maintaining our fork to continue
the exclusions from the impl archive (I believe we
separate the API classes so that we can prevent exposing
impl classes to deployments, fwiw).
What I would like to propose and get some feedback on
is creating a new module in https://github.com/eclipse-ee4j/mojarra/
to move the jakarta.* classes to a new module (e.g.,
api) and add a dependency on that to impl. I think that
would also require some sort of change in
jakarta.faces:jakarta.faces-api to adapt to that (unless
this new module simply published under that G:A if
Central would allow it).
Does anyone see a reason for NOT doing that? Things
usually have a reason for being the way the are, so if
I'm missing something, please educate me before I put
the work in to create a PR. :P