Skip to content

TOMEE-4662 - Speed up annotation processing during WAR deploy - #2856

Open
tandraschko wants to merge 2 commits into
apache:mainfrom
tandraschko:main
Open

TOMEE-4662 - Speed up annotation processing during WAR deploy#2856
tandraschko wants to merge 2 commits into
apache:mainfrom
tandraschko:main

Conversation

@tandraschko

Copy link
Copy Markdown
Member

Speed up annotation processing during WAR deploy

OpenEJBContextConfig.isIncluded() resolves the canonical path of the module
roots and of the web resource on every call, and Tomcat calls
processAnnotationsWebResource() once per web resource. On a WAR with a few
hundred classes under WEB-INF/classes that is thousands of filesystem
syscalls, most of them resolving the same handful of paths again and again.
Three changes, no behaviour change:

  • Memoise File.getCanonicalFile() and the URL to File conversion. Both
    mappings are stable for the lifetime of a deploy and the config instance is
    per context.
  • Return early from processAnnotationsWebResource() once every module has
    been processed. There is nothing left to match the resource against, and that
    branch never delegates to super, so resolving the resource is wasted work.
  • Reuse the path from FileResource.getCanonicalPath() instead of letting
    isIncluded() resolve the same, already canonical, path a second time.
    Measured on a synthetic WAR (40 jars, 513 classes in WEB-INF/classes) with
    tomee-embedded: isIncluded() accounted for 165 of 468 deploy-phase profiler
    samples before the change and 1 after, and deploy wall time dropped ~25%.
    Note this was measured on Windows, where getCanonicalPath() is considerably
    more expensive than on Linux, so expect a smaller gain there.

Also see apache/tomcat#1030

@jungm

jungm commented Jul 29, 2026

Copy link
Copy Markdown
Member

@jungm

jungm commented Jul 31, 2026

Copy link
Copy Markdown
Member

Nice speedup, logic checks out. Two changes I'd make before merge:

  1. Use ConcurrentHashMap for both caches. With parallelAnnotationScanning="true", Tomcat runs processAnnotationsUrl on multiple utility-executor threads, which reaches the maps via internalProcessAnnotationsisIncludedIn. Concurrent puts into a plain HashMap can lose entries or corrupt the table.

  2. Clear both maps in configureStop(), like webInfClassesAnnotationsProcessed. The listener survives context stop/start, so after a reload canonicalFiles can hold stale resolutions (symlinks/paths may have changed), and both maps otherwise retain ~one entry per class file for the life of the context.

Also: please file a TOMEE JIRA and reference it in the title/commit, per project convention.

@tandraschko

Copy link
Copy Markdown
Member Author

@jungm jungm changed the title Speed up annotation processing during WAR deploy TOMEE-4662 - Speed up annotation processing during WAR deploy Jul 31, 2026
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