I'm currently thinking that the Portable Extensions approach,
where the "observer" methods on the extension class are themselves
callbacks, might actually be better, if we really need to be
push-based. I'll probably explore that approach too, to see how it
would look like.
LT
On 30. 09. 20 14:14, Ladislav Thon
wrote:
Ah, one more thing. We also got a very good feedback from
Graeme on the current proposal [1], and we'll work on
incorporating that. So any and all examples should be considered
temporary and subject to change. I've been saying that since the
beginning, so hopefully it doesn't come up as a surprise :-)
OK, I got carried away a bit too much. Please disregard the
"replace" word -- at this point, it's way premature. Let's say
"find an alternative". What it really becomes in the end is
hard to know at this point.
Sorry, and thanks for understanding.
LT
with a mechanism that is similarly powerful, caters to
similar use cases, but removes an important architectural
constraint (the need for everything to run in a single JVM).
As a developer, I want to use the CDI
extension to:
Providing its own beans, interceptors and
decorators to the container
The `@Discovery` phase has a method to add arbitrary
classes to the "application". If such class doesn't have a
bean defining annotation etc., you can add those annotation
in the `@Enhancement` phase.
Injecting dependencies into its own objects using
the dependency injection service
Sorry, I'm not sure what this means.
Is this about extension-contributed classes being treated
as application classes, i.e. can have dependencies injected
and themselves being injected, can declare observers, etc.
etc.? If so, then sure, I'd say that's a given.
Or is this about being able to access the extension
instance at application runtime? That would be a no-no I'm
afraid. The instance is potentially long gone when the
application starts. The class is potentially a different
class (loaded by a different classloader in a different
JVM).
Providing a context implementation for a custom
scope
The `@Discovery` phase has a method to register custom
context class. If the class doesn't have all the necessary
metadata (such as the scope annotation), the API also has
methods to set those.
Augmenting or overriding the annotation-based
metadata with metadata from some other source
The `@Enhancement` phase is all about this.
There's also an API to add synthetic beans and observers
(`@Synthesis`), and an API for validating the application
and preventing successful build/deployment (`@Validation`).
To sum up, the most important use cases for CDI extensions,
as far as I can tell, are covered.
LT, can you double check whether this is the use case
your PR is for? It will be very appreciated if you can
put some code snippets to demonstrate how to achieve
some of the use cases.
OK, let me try.
Registering a custom context:
public class MyContext implements AlterableContext { ... }
public class MyExtension {
@Discovery
public void customContext(Contexts contexts) {
contexts.add().implementation(MyContext.class);
}
}
Contributing a bean to the application:
@ApplicationScoped
public class MyBean { ... }
public class MyExtension {
@Discovery
public void customBean(AppArchiveBuilder app) {
app.add(MyBean.class);
}
}
Contributing a non-bean class to the application and making
it a bean:
public class MyBean { ... }
public class MyExtension {
@Discovery
public void customClass(AppArchiveBuilder app) {
app.add(MyBean.class);
}
@Enhancement
public void makeItABean(ClassConfig<MyBean> bean) {
bean.addAnnotation(ApplicationScoped.class);
}
}
Vetoing a bean:
public class MyExtension {
@Enhancement
public void vetoABean(ClassConfig<SomeBean> bean) {
bean.addAnnotation(Vetoed.class);
}
}
Makes sense? I know these are toy examples, but should give
you an idea.
LT
If you can't deal with some of the use cases listed
above, we can discuss here on whether we should reduce
the scope or we can suggest some alternative solutions.
Thanks,
Emily
On Wed, Sep 30, 2020 at
9:41 AM Ladislav Thon <lthon@xxxxxxxxxx>
wrote:
Yes. With (truly!!) all
respect to Antoine, it's a bit
all over the place and not a
list of use cases or goals.
Can we just put down here, in
simple bullet point formats,
what at least the goals of this
effort are?
I don't mean to suggest this
is a trivial exercise, because
it is not, and Emily certainly
tried to get it rolling before
(mostly unsuccessfully) with
issue #425 (https://github.com/eclipse-ee4j/cdi/issues/425;
and I applaud her attempt to
start with the use cases). But
let's try again, here, publicly,
on this list.
For the record, I'm
definitely aware of {handwave}
build time {handwave} no
reflection {handwave} but I'm
quite sure we can do better than
that as a group. Here is an
incomplete sketch of one example
of the sort of thing I had in
mind.
Meta-goal: disrupt the
specification as little as
humanly possible (true of all
specifications everywhere that
are this old)
Goal: permit a CDI
SeContainer to run a precomputed
set of beans without having to
run portable extensions
Why: certain products create
their beans at build time/ahead
of time: we want them to be part
of the CDI fold as well
Hindrance: the
SeContainerInitializer/portable
extension APIs, even with
something like
SeContainerInitializer.disableDiscovery().addExtension(new
Extension() { /* add beans here
however they are
generated/created */ }) is
insufficient because of X, Y and
Z
Hindrance: all (not just
some) portable extensions must
be available at runtime via
BeanManager#getExtension()
…etc. and so on. I can see
the germs of something like this
lurking in your posts and
others' and in Antoine's blog
article and elsewhere but I
think it is necessary that we
have small, traceable,
actionable goals spelled out
here before we try to solve
them.
So I think we have explained the why
quite a bit, and importantly we are
talking about fundamental compatibility
differences (two-phase multi-VM execution
vs one phase), so you are already at the
point of having to start anew. It’s not
something that a simple API tweak here and
there is going to solve.
Totally agree. I'd highlight what you put into
parens :-) I have never considered it a use case, or
anything worth extra mentioning, which in hindsight
is an obivous mistake, so let me try to phrase it
concretely.
Goal: modify the specification and the APIs to no
longer assume that everything happens in a single
JVM. It should be possible for a big part of the
"application initialization lifecycle", including
extensions, to run in another JVM, to "pre-wire" the
application statically and enable significant
performance gains during actual application startup.
(I understand this might not necessarily be a SMART
goal. Sorry about that, I'm a simple man and prefer
debating concrete ideas rather than abstract
methodologies.)
Just a small clarification that I am
specifically referring to portable extensions
(#434) and the proposal (#451) which is the
subject of this thread. This is the area that
requires a reboot, to cover the same extension
author use cases.
The other areas of CDI are less of a problem,
each of those items will have their own issue
against them (which might involve small spec
wording changes). Some of them might be future
decision points (should lite include X yes/no?)
However, the hardest part of a potential CDI-Lite
is solving the portable extension problem, so IMO
it makes sense to tackle this area first. FWIW we
new this would tough, so we first proposed just
leaving this aspect to venders, but a number of
commenters really wanted to see work on a new SPI.
So here we go :)