Skip to content

Let applications restrict which classes wicket-cdi injects - #1569

Open
pedrosans wants to merge 1 commit into
apache:masterfrom
pedrosans:cdi-filter
Open

Let applications restrict which classes wicket-cdi injects#1569
pedrosans wants to merge 1 commit into
apache:masterfrom
pedrosans:cdi-filter

Conversation

@pedrosans

Copy link
Copy Markdown
Contributor

CdiConfiguration now takes a Predicate<Class<?>> deciding whether a class
is an injection candidate, and ComponentInjector, BehaviorInjector and
SessionInjector consult it before entering CDI. The default accepts every
class, so nothing changes unless an application opts in.

Every Component and Behavior instantiation goes through NonContextual,
which resolves the BeanManager twice, creates a CreationalContext and
calls InjectionTarget#inject, even for the many framework classes that
declare no injection point at all. The InjectionTarget is cached per
class, so nothing is rescanned, but that surrounding work is repeated per
instance.

It is cheap on a bare Weld container, which registers no InjectionServices
and goes straight to Weld's own injection. It need not be cheap on a
Jakarta EE container, where the integrator registers an InjectionServices
of its own and Weld calls aroundInject on every InjectionTarget#inject,
whether or not the class has anything to inject. That hook is where the
container performs @resource, @PersistenceContext, @PersistenceUnit, @ejb
and @WebServiceRef injection, and the SPI leaves it to the integrator
whether to cache the metadata parsed there. An application whose
components need no injection can now skip the call rather than pay for it
once per component.

A rejected class gets no CDI at all: no @Inject, none of the resource
injection above, and no @PostConstruct on a Session. None of those are
reported by InjectionTarget#getInjectionPoints, so a filter that rejects
too much fails silently. Hence the filter is opt-in and the default
accepts everything.

wicket-cdi's own listeners inject themselves through NonContextual
directly and are never filtered, and neither is the application, which
CdiConfiguration#configure injects itself.

@codecov-commenter

codecov-commenter commented Sep 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.88%. Comparing base (788c0c3) to head (fb70a76).

Additional details and impacted files
@@             Coverage Diff              @@
##             master    #1569      +/-   ##
============================================
+ Coverage     61.85%   61.88%   +0.03%     
- Complexity    11180    11191      +11     
============================================
  Files          1245     1245              
  Lines         48220    48227       +7     
  Branches       6759     6759              
============================================
+ Hits          29825    29845      +20     
+ Misses        15694    15682      -12     
+ Partials       2701     2700       -1     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

CdiConfiguration now takes a Predicate<Class<?>> deciding whether a class
is an injection candidate, and ComponentInjector, BehaviorInjector and
SessionInjector consult it before entering CDI. The default accepts every
class, so nothing changes unless an application opts in.

Every Component and Behavior instantiation goes through NonContextual,
which resolves the BeanManager twice, creates a CreationalContext and
calls InjectionTarget#inject, even for the many framework classes that
declare no injection point at all. The InjectionTarget is cached per
class, so nothing is rescanned, but that surrounding work is repeated per
instance.

It is cheap on a bare Weld container, which registers no InjectionServices
and goes straight to Weld's own injection. It need not be cheap on a
Jakarta EE container, where the integrator registers an InjectionServices
of its own and Weld calls aroundInject on every InjectionTarget#inject,
whether or not the class has anything to inject. That hook is where the
container performs @resource, @PersistenceContext, @PersistenceUnit, @ejb
and @WebServiceRef injection, and the SPI leaves it to the integrator
whether to cache the metadata parsed there. An application whose
components need no injection can now skip the call rather than pay for it
once per component.

A rejected class gets no CDI at all: no @Inject, none of the resource
injection above, and no @PostConstruct on a Session. None of those are
reported by InjectionTarget#getInjectionPoints, so a filter that rejects
too much fails silently. Hence the filter is opt-in and the default
accepts everything.

wicket-cdi's own listeners inject themselves through NonContextual
directly and are never filtered, and neither is the application, which
CdiConfiguration#configure injects itself.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants