Jose Miguel created WW-5667:
-------------------------------

             Summary: Performance Issue: SecurityMemberAccess re-parses 
excluded packages/classes config string on every OGNL access — O(n) 
String.split per request
                 Key: WW-5667
                 URL: https://issues.apache.org/jira/browse/WW-5667
             Project: Struts 2
          Issue Type: Bug
            Reporter: Jose Miguel


In stress test is consuming 9% of a server with 4 CPUs.

**Struts version:** 7.2.1
**JDK:** 21 (OpenJDK ms-21.0.7)
**JVM flags:** Payara 7.2026.6

**Summary:**
`SecurityMemberAccess.isClassBelongsToPackages()` and the related
`useExcludedPackageNames()` / `useExcludedClasses()` methods call
`ConfigParseUtil.toNewPackageNamesSet()` / `toNewClassesSet()` on every
OGNL member-access check, which calls `String.split()` and builds a new
`HashSet` each time from the raw config string.

Under moderate load (preprod server, ~20% Payara CPU) this accounts for
~9% of all RUNNABLE CPU samples in a 2-minute JFR profile.

**Stack traces (JFR ExecutionSamples, STATE_RUNNABLE):**

Sample 1:
  java.lang.String.split(String)
  SecurityMemberAccess.isClassBelongsToPackages(Class, Set) :390
  SecurityMemberAccess.isExcludedPackageNames(Class) :386
  SecurityMemberAccess.isPackageExcluded(Class) :371

Sample 2:
  HashMap.put / HashSet.add
  ConfigParseUtil.toNewPackageNamesSet(Collection, String) :138
  SecurityMemberAccess.useExcludedPackageNames(String) :446

**Proposed fix:**
Cache the parsed `Set<String>` in `SecurityMemberAccess` as a field.
Rebuild it only when the raw config string reference changes (compare
with `==` or store the last-seen string). Since the excluded-packages
config is set once at startup and never changes at runtime, the cache
never needs invalidation in practice.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to