Skip to content

Bug Report: [Performance Regression] AgenticAIExtension adds unconditional per-deployment overhead to every CDI application #8489

Open

Description

@lprimak

Brief Summary

Since the Jakarta Agentic AI module was merged (#8331, on main since 2026-08-10, shipped in Server Full/Web, Micro and Embedded), application deployment has become noticeably slower (roughly 3–5 extra seconds) per typical deployment on typical hardware. The cause is fish.payara.ai.agent.extension.AgenticAIExtension (appserver/agentic-ai/agentic-ai-core), a server-wide CDI portable extension that is loaded into every CDI deployment and does work proportional to the application size, plus expensive fixed-cost bootstrapping, regardless of whether the application contains any @Agent class.

Three concrete problems in AgenticAIExtension.java:

  1. Unfiltered ProcessAnnotatedType observer (line 113)

    <X> void processAgent(@Observes ProcessAnnotatedType<X> processAnnotatedType) {
        var annotatedType = processAnnotatedType.getAnnotatedType();
        if (!annotatedType.isAnnotationPresent(Agent.class)) {
            return;
        }

    There is no @WithAnnotations(Agent.class). Weld can only use its fast PAT resolution path (skipping event dispatch for types that do not carry the requested annotations) when all PAT observers are filtered. A single unfiltered observer forces Weld to construct and fire a ProcessAnnotatedType event for every class in every bean archive of every application. This is the only unfiltered PAT observer in the whole server; all other server-wide extensions filter correctly:

    • web-sse/.../ServerSentEventCdiExtension.java:188 → @WithAnnotations(ServerSentEvent.class)
    • microprofile/config/.../ConfigCdiExtension.java:121 → @WithAnnotations(ConfigProperties.class)
    • payara-micro-cdi/.../PayaraMicroCDIExtension.java:77 → @WithAnnotations(Clustered.class)
    • gf-jms-injection/.../JMSCDIExtension.java:104 → @WithAnnotations(Void.class)
  2. Eager Bean Validation bootstrap on every deployment (lines 167 and 283)

    void afterBeanDiscovery(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager) {
        ...
        WorkflowEngine workflowEngine = new WorkflowEngine(beanManager, workflowScopeManager, resolveExecutableValidator());
    ...
    private ExecutableValidator resolveExecutableValidator() {
        return Validation.buildDefaultValidatorFactory().getValidator().forExecutables();

    Validation.buildDefaultValidatorFactory() performs a full Hibernate Validator bootstrap (provider resolution via ServiceLoader against the application class loader, META-INF/validation.xml parsing, message interpolator / EL setup, constraint validator discovery). It runs unconditionally, even when agentClasses is empty — and the resulting ValidatorFactory is never closed. It is also a second, separate factory from the one the container already manages for the application.

  3. Eager MicroProfile Config resolution on every deployment (line 184)

    if (!appProvidesLlm) {
        LlmBackend backend = LlmBackendFactory.create(ConfigProvider.getConfig());
        afterBeanDiscovery.addBean()...

    ConfigProvider.getConfig() forces construction of the application's MP Config (including scanning the app class loader for META-INF/microprofile-config.properties) for every deployment, and registers a synthetic LargeLanguageModel bean in every application whether or not the application has anything to do with Agentic AI.

Expected Outcome

Applications that do not use Jakarta Agentic AI should pay no measurable deployment-time cost for the module. Specifically:

  • The ProcessAnnotatedType observer should be restricted with @WithAnnotations(Agent.class) so Weld's fast path remains available and the observer is only invoked for actual @Agent types.
  • Bean Validation (Validation.buildDefaultValidatorFactory()), MP Config lookup and the synthetic default LargeLanguageModel bean should only be set up when at least one @Agent class was discovered (!agentClasses.isEmpty()), or lazily on first workflow execution.
  • Any ValidatorFactory the extension creates should be closed on shutdown (BeforeShutdown) or the container-managed one should be reused.

Deployment times should return to pre‑#8331 levels for non-Agentic-AI applications.

Current Outcome

Every CDI application deployment on Payara ≥ 7.2026.9 (where appserver/agentic-ai is bundled):

  • fires a ProcessAnnotatedType event for every class in the application (Weld fast PAT resolver disabled),
  • bootstraps a full, never-closed Hibernate Validator ValidatorFactory,
  • builds the application's MP Config,
  • gets a synthetic LargeLanguageModel bean registered.

The result is roughly 3–5 seconds of additional deployment time per typical application on typical developer hardware, compared with 7.2026.8 and earlier. The overhead scales with application size (number of classes), so large applications (thousands of classes, many bean archives) are affected the most.

Reproducer

  1. Take any CDI web application with a large number of classes (e.g. a few thousand) and no @Agent class. A simple way to amplify the effect is a WAR with a beans.xml using bean-discovery-mode="all" and a few thousand trivial classes, or any sizeable real-world application.
  2. Deploy on Payara Community 7.2026.8 (before FISH-14066 Jakarta Agentic AI: use released API 1.0.0-M1 and EE11 TCK branch #8331) and measure deployment time (e.g. asadmin deploy wall-clock time, or the DeploymentTracing output).
  3. Deploy the same application on 7.2026.9 / 7.2026.10 / current main and measure again. Deployment takes roughly 3–5 seconds longer for a typical application.
  4. To confirm the attribution, remove agentic-ai-core.jar (or the jakarta.agentic-ai-api + agentic-ai-core bundles) from glassfish/modules and redeploy — deployment time returns to the 7.2026.8 level.
  5. Alternatively, rebuild agentic-ai-core with @WithAnnotations(Agent.class) on processAgent and guard the afterBeanDiscovery work behind !agentClasses.isEmpty(); the regression disappears.

Code evidence (current main): appserver/agentic-ai/agentic-ai-core/src/main/java/fish/payara/ai/agent/extension/AgenticAIExtension.java lines 113, 167, 184, 283.

Operating System

Any

JDK Version

Any Supported

Payara Distribution

  • Payara Server Full Profile
  • Payara Server Web Profile
  • Payara Micro
  • Payara Embedded All
  • Payara Embedded Web

Suggested fix

<X> void processAgent(@Observes @WithAnnotations(Agent.class) ProcessAnnotatedType<X> processAnnotatedType) { ... }

void afterBeanDiscovery(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager) {
    if (agentClasses.isEmpty()) {
        return;   // nothing to do for applications without agents
    }
    ...
}

plus closing the ValidatorFactory on BeforeShutdown. Happy to submit a PR for this.

Activity

  1. added
    Status: OpenIssue has been triaged by the front-line engineers and is being worked on verification
    on Oct 8, 2026
  2. changed the title [-]Bug Report: AgenticAIExtension adds unconditional per-deployment overhead to every CDI application (unfiltered ProcessAnnotatedType observer, eager Bean Validation bootstrap)[/-] [+]Bug Report: [Performance Regression] AgenticAIExtension adds unconditional per-deployment overhead to every CDI application[/+] on Oct 8, 2026
  3. added
    Status: AcceptedConfirmed defect or accepted improvement to implement, issue has been escalated to Platform Dev
    Type: BugLabel issue as a bug defect
    and removed
    Status: OpenIssue has been triaged by the front-line engineers and is being worked on verification
    on Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Status: AcceptedConfirmed defect or accepted improvement to implement, issue has been escalated to Platform DevType: BugLabel issue as a bug defect

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions