0

Examples for creating a portable CDI Extension (like this) all use the javax.enterprise.inject.spi.Extension extension point to allow the ServiceLoader to load the Extension.

Is there a Weld/CDI API/SPI to register the Extension dynamically, programmatically?

I realize the lifecycle might be an issue since you've started the app without this extension present and perhaps it's "too late" in some aspects, but wanted to ask anyway. Specifically I'm wondering about an EE environment.

Scott Kurz
  • 4,985
  • 1
  • 18
  • 40

2 Answers2

2

To give a short answer - CDI intentionally provides no API to dynamically add extensions. And in fact, you shouldn't be trying to achieve that.

A bit of why:

CDI is static in it's nature - it needs certain information during bootstrap and extension is one of them. Once that bootstrap is done, the extension mostly become useless (granted, you can still use them as beans and have some logic there, but it's 'just a bean' then). The reason is that extensions hook into bootstrap cycle and can affect each and every phase (ProcessAnnotatedType, ProcessBeanAttributes, ...).

Now, if you somehow loaded such an extension later on (e.g. with booted CDI container) there would be two options; either re-load whole CDI container to take this extension into consideration, or ignore it's contents entirely, making it totally useless as it would act as an ordinary bean (the container lifecycle observer would never get invoked). The former would be very costly/disturbing in certain deployment and might lead to unpredictable results - imagine such dynamic extensions shuffling with alternatives and specialization. The latter case makes little to no sense as it would add a never used bean. That's why CDI doesn't allow this in general.

I wonder, what is your use case? If we knew that, perhaps we might help you sort that out in a different way.

Siliarus
  • 6,393
  • 1
  • 14
  • 30
  • Thanks. In my use case the other answer, getting control but then guarding the logic to make further calls on **BeforeBeanDiscovery** with some other property, is a good fit. Was curious if this was indeed the design intention, so accepting this answer since it addresses that. – Scott Kurz May 16 '17 at 12:36
  • One use case would be to add an observer for `processAnnotatedType` with no `@WithAnnotations` only under special circumstances, e.g. only when in Jersey the `Hk2CustomBoundTypesProvider` has been defined. – Arjan Tijms Feb 18 '18 at 16:19
1

As far as i know there is no official API to support this.

I am aware of two hacks/options you might want to try depending on your use case.

  • Add a custom classloader that dynamically creates the spi service file

  • You can look at the source of cdi unit. Last time i looked, it used reflection and implementation specific classes to access the internals of Weld to influence the initialization. I would NOT recomend that method for other things than tests.

Why do you want to load the extensions dynamically?

One easy solution might be to always load the extension and have it decide to actually do something.

k5_
  • 5,450
  • 2
  • 19
  • 27
  • Thx. Agree the easy solution of loading it and adding a toggle in the logic is sounding good compared to those! – Scott Kurz May 12 '17 at 14:51