Fix ClassCastException in CSI generator when advice captures multiple partial arguments#11130
Fix ClassCastException in CSI generator when advice captures multiple partial arguments#11130
Conversation
…-argument advice Stream.sorted() without a comparator requires Comparable, but ArgumentSpecification does not implement it. This caused a ClassCastException in AdviceGeneratorImpl.writeStackOperations whenever an advice method captured a strict subset (≥2 args) of a target method's parameters positionally — e.g. capturing args 0 and 1 from a 3-arg target method. Single-argument partial captures were unaffected because TimSort never calls compare() on a one-element list. Fix: use Comparator.comparingInt on ArgumentSpecification.getIndex(). Add a regression test with a @before advice that captures two of three arguments from String.format(Locale, String, Object[]).
|
Hi! 👋 Thanks for your pull request! 🎉 To help us review it, please make sure to:
If you need help, please check our contributing guidelines. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7525934416
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…x generation
Stream.sorted() without a comparator requires Comparable, but
ArgumentSpecification does not implement it, causing ClassCastException
when an advice method captures two or more arguments positionally from a
target method that has strictly more parameters.
The parameters map is a TreeMap keyed by advice-parameter index, so
Stream.sorted() was both redundant and incorrect: it would have
re-sorted by natural order (broken) or by pointcut index (wrong for
advices that intentionally reorder captures). Removing it preserves the
TreeMap's advice-parameter-index order, which is what dupParameters
and the advice descriptor both expect.
Add MultiplePartialArgumentsBeforeAdvice with two variants:
- In-order capture (args 0,1 from 3-arg method): generates {0,1}
- Reversed capture (arg 1 then arg 0): generates {1,0} not {0,1},
proving parameterIndices follows advice-parameter order.
BenchmarksStartupParameters
See matching parameters
SummaryFound 0 performance improvements and 0 performance regressions! Performance is the same for 56 metrics, 15 unstable metrics. Startup time reports for insecure-bankgantt
title insecure-bank - global startup overhead: candidate=1.62.0-SNAPSHOT~696c0e308c, baseline=1.62.0-SNAPSHOT~42f154d2f6
dateFormat X
axisFormat %s
section tracing
Agent [baseline] (1.055 s) : 0, 1054819
Total [baseline] (8.843 s) : 0, 8843464
Agent [candidate] (1.055 s) : 0, 1054590
Total [candidate] (8.849 s) : 0, 8848642
section iast
Agent [baseline] (1.223 s) : 0, 1223220
Total [baseline] (9.534 s) : 0, 9533612
Agent [candidate] (1.224 s) : 0, 1223875
Total [candidate] (9.602 s) : 0, 9601761
gantt
title insecure-bank - break down per module: candidate=1.62.0-SNAPSHOT~696c0e308c, baseline=1.62.0-SNAPSHOT~42f154d2f6
dateFormat X
axisFormat %s
section tracing
crashtracking [baseline] (1.241 ms) : 0, 1241
crashtracking [candidate] (1.216 ms) : 0, 1216
BytebuddyAgent [baseline] (632.602 ms) : 0, 632602
BytebuddyAgent [candidate] (630.634 ms) : 0, 630634
AgentMeter [baseline] (29.304 ms) : 0, 29304
AgentMeter [candidate] (29.266 ms) : 0, 29266
GlobalTracer [baseline] (248.071 ms) : 0, 248071
GlobalTracer [candidate] (247.912 ms) : 0, 247912
AppSec [baseline] (32.314 ms) : 0, 32314
AppSec [candidate] (32.435 ms) : 0, 32435
Debugger [baseline] (58.98 ms) : 0, 58980
Debugger [candidate] (59.394 ms) : 0, 59394
Remote Config [baseline] (600.217 µs) : 0, 600
Remote Config [candidate] (604.36 µs) : 0, 604
Telemetry [baseline] (8.063 ms) : 0, 8063
Telemetry [candidate] (8.065 ms) : 0, 8065
Flare Poller [baseline] (7.451 ms) : 0, 7451
Flare Poller [candidate] (8.91 ms) : 0, 8910
section iast
crashtracking [baseline] (1.241 ms) : 0, 1241
crashtracking [candidate] (1.215 ms) : 0, 1215
BytebuddyAgent [baseline] (800.932 ms) : 0, 800932
BytebuddyAgent [candidate] (801.398 ms) : 0, 801398
AgentMeter [baseline] (11.349 ms) : 0, 11349
AgentMeter [candidate] (11.422 ms) : 0, 11422
GlobalTracer [baseline] (238.78 ms) : 0, 238780
GlobalTracer [candidate] (239.129 ms) : 0, 239129
IAST [baseline] (25.814 ms) : 0, 25814
IAST [candidate] (25.737 ms) : 0, 25737
AppSec [baseline] (32.608 ms) : 0, 32608
AppSec [candidate] (29.574 ms) : 0, 29574
Debugger [baseline] (60.309 ms) : 0, 60309
Debugger [candidate] (63.602 ms) : 0, 63602
Remote Config [baseline] (545.887 µs) : 0, 546
Remote Config [candidate] (543.478 µs) : 0, 543
Telemetry [baseline] (11.824 ms) : 0, 11824
Telemetry [candidate] (11.748 ms) : 0, 11748
Flare Poller [baseline] (3.494 ms) : 0, 3494
Flare Poller [candidate] (3.433 ms) : 0, 3433
Startup time reports for petclinicgantt
title petclinic - global startup overhead: candidate=1.62.0-SNAPSHOT~696c0e308c, baseline=1.62.0-SNAPSHOT~42f154d2f6
dateFormat X
axisFormat %s
section tracing
Agent [baseline] (1.057 s) : 0, 1057485
Total [baseline] (11.255 s) : 0, 11255011
Agent [candidate] (1.067 s) : 0, 1067282
Total [candidate] (11.083 s) : 0, 11082768
section appsec
Agent [baseline] (1.258 s) : 0, 1258022
Total [baseline] (11.089 s) : 0, 11089338
Agent [candidate] (1.262 s) : 0, 1261945
Total [candidate] (11.167 s) : 0, 11167130
section iast
Agent [baseline] (1.242 s) : 0, 1242343
Total [baseline] (11.375 s) : 0, 11375367
Agent [candidate] (1.226 s) : 0, 1225920
Total [candidate] (11.25 s) : 0, 11250335
section profiling
Agent [baseline] (1.186 s) : 0, 1186339
Total [baseline] (11.115 s) : 0, 11115023
Agent [candidate] (1.19 s) : 0, 1189522
Total [candidate] (11.056 s) : 0, 11055509
gantt
title petclinic - break down per module: candidate=1.62.0-SNAPSHOT~696c0e308c, baseline=1.62.0-SNAPSHOT~42f154d2f6
dateFormat X
axisFormat %s
section tracing
crashtracking [baseline] (1.226 ms) : 0, 1226
crashtracking [candidate] (1.233 ms) : 0, 1233
BytebuddyAgent [baseline] (630.811 ms) : 0, 630811
BytebuddyAgent [candidate] (638.392 ms) : 0, 638392
AgentMeter [baseline] (29.414 ms) : 0, 29414
AgentMeter [candidate] (29.396 ms) : 0, 29396
GlobalTracer [baseline] (248.729 ms) : 0, 248729
GlobalTracer [candidate] (250.502 ms) : 0, 250502
AppSec [baseline] (32.383 ms) : 0, 32383
AppSec [candidate] (32.625 ms) : 0, 32625
Debugger [baseline] (60.12 ms) : 0, 60120
Debugger [candidate] (60.349 ms) : 0, 60349
Remote Config [baseline] (589.775 µs) : 0, 590
Remote Config [candidate] (619.699 µs) : 0, 620
Telemetry [baseline] (8.056 ms) : 0, 8056
Telemetry [candidate] (8.197 ms) : 0, 8197
Flare Poller [baseline] (9.985 ms) : 0, 9985
Flare Poller [candidate] (9.746 ms) : 0, 9746
section appsec
crashtracking [baseline] (1.239 ms) : 0, 1239
crashtracking [candidate] (1.233 ms) : 0, 1233
BytebuddyAgent [baseline] (667.145 ms) : 0, 667145
BytebuddyAgent [candidate] (666.889 ms) : 0, 666889
AgentMeter [baseline] (12.153 ms) : 0, 12153
AgentMeter [candidate] (12.219 ms) : 0, 12219
GlobalTracer [baseline] (251.09 ms) : 0, 251090
GlobalTracer [candidate] (252.395 ms) : 0, 252395
AppSec [baseline] (185.912 ms) : 0, 185912
AppSec [candidate] (187.821 ms) : 0, 187821
Debugger [baseline] (66.461 ms) : 0, 66461
Debugger [candidate] (66.774 ms) : 0, 66774
Remote Config [baseline] (642.651 µs) : 0, 643
Remote Config [candidate] (608.388 µs) : 0, 608
Telemetry [baseline] (8.504 ms) : 0, 8504
Telemetry [candidate] (8.621 ms) : 0, 8621
Flare Poller [baseline] (3.563 ms) : 0, 3563
Flare Poller [candidate] (3.671 ms) : 0, 3671
IAST [baseline] (24.748 ms) : 0, 24748
IAST [candidate] (25.051 ms) : 0, 25051
section iast
crashtracking [baseline] (1.25 ms) : 0, 1250
crashtracking [candidate] (1.238 ms) : 0, 1238
BytebuddyAgent [baseline] (814.473 ms) : 0, 814473
BytebuddyAgent [candidate] (803.507 ms) : 0, 803507
AgentMeter [baseline] (11.895 ms) : 0, 11895
AgentMeter [candidate] (11.34 ms) : 0, 11340
GlobalTracer [baseline] (241.921 ms) : 0, 241921
GlobalTracer [candidate] (238.788 ms) : 0, 238788
AppSec [baseline] (33.273 ms) : 0, 33273
AppSec [candidate] (29.407 ms) : 0, 29407
Debugger [baseline] (59.177 ms) : 0, 59177
Debugger [candidate] (62.299 ms) : 0, 62299
Remote Config [baseline] (551.509 µs) : 0, 552
Remote Config [candidate] (533.497 µs) : 0, 533
Telemetry [baseline] (13.172 ms) : 0, 13172
Telemetry [candidate] (11.103 ms) : 0, 11103
Flare Poller [baseline] (3.604 ms) : 0, 3604
Flare Poller [candidate] (3.456 ms) : 0, 3456
IAST [baseline] (26.172 ms) : 0, 26172
IAST [candidate] (28.007 ms) : 0, 28007
section profiling
ProfilingAgent [baseline] (93.927 ms) : 0, 93927
ProfilingAgent [candidate] (94.009 ms) : 0, 94009
crashtracking [baseline] (1.19 ms) : 0, 1190
crashtracking [candidate] (1.191 ms) : 0, 1191
BytebuddyAgent [baseline] (692.788 ms) : 0, 692788
BytebuddyAgent [candidate] (696.168 ms) : 0, 696168
AgentMeter [baseline] (9.14 ms) : 0, 9140
AgentMeter [candidate] (9.112 ms) : 0, 9112
GlobalTracer [baseline] (207.687 ms) : 0, 207687
GlobalTracer [candidate] (207.076 ms) : 0, 207076
AppSec [baseline] (32.861 ms) : 0, 32861
AppSec [candidate] (32.771 ms) : 0, 32771
Debugger [baseline] (65.475 ms) : 0, 65475
Debugger [candidate] (65.57 ms) : 0, 65570
Remote Config [baseline] (572.129 µs) : 0, 572
Remote Config [candidate] (572.498 µs) : 0, 572
Telemetry [baseline] (7.816 ms) : 0, 7816
Telemetry [candidate] (7.817 ms) : 0, 7817
Flare Poller [baseline] (3.547 ms) : 0, 3547
Flare Poller [candidate] (3.574 ms) : 0, 3574
Profiling [baseline] (94.501 ms) : 0, 94500
Profiling [candidate] (94.596 ms) : 0, 94596
LoadParameters
See matching parameters
SummaryFound 0 performance improvements and 3 performance regressions! Performance is the same for 18 metrics, 15 unstable metrics.
Request duration reports for petclinicgantt
title petclinic - request duration [CI 0.99] : candidate=1.62.0-SNAPSHOT~696c0e308c, baseline=1.62.0-SNAPSHOT~42f154d2f6
dateFormat X
axisFormat %s
section baseline
no_agent (18.105 ms) : 17923, 18288
. : milestone, 18105,
appsec (18.659 ms) : 18470, 18847
. : milestone, 18659,
code_origins (17.918 ms) : 17742, 18093
. : milestone, 17918,
iast (18.009 ms) : 17830, 18187
. : milestone, 18009,
profiling (18.125 ms) : 17945, 18305
. : milestone, 18125,
tracing (17.718 ms) : 17543, 17892
. : milestone, 17718,
section candidate
no_agent (18.175 ms) : 17994, 18357
. : milestone, 18175,
appsec (18.561 ms) : 18372, 18749
. : milestone, 18561,
code_origins (18.067 ms) : 17893, 18240
. : milestone, 18067,
iast (17.866 ms) : 17690, 18041
. : milestone, 17866,
profiling (18.328 ms) : 18148, 18508
. : milestone, 18328,
tracing (19.181 ms) : 18983, 19379
. : milestone, 19181,
Request duration reports for insecure-bankgantt
title insecure-bank - request duration [CI 0.99] : candidate=1.62.0-SNAPSHOT~696c0e308c, baseline=1.62.0-SNAPSHOT~42f154d2f6
dateFormat X
axisFormat %s
section baseline
no_agent (1.258 ms) : 1246, 1271
. : milestone, 1258,
iast (3.384 ms) : 3336, 3432
. : milestone, 3384,
iast_FULL (6.127 ms) : 6065, 6190
. : milestone, 6127,
iast_GLOBAL (3.644 ms) : 3593, 3695
. : milestone, 3644,
profiling (2.43 ms) : 2404, 2456
. : milestone, 2430,
tracing (1.882 ms) : 1866, 1898
. : milestone, 1882,
section candidate
no_agent (1.245 ms) : 1232, 1257
. : milestone, 1245,
iast (3.377 ms) : 3329, 3424
. : milestone, 3377,
iast_FULL (6.331 ms) : 6265, 6397
. : milestone, 6331,
iast_GLOBAL (3.679 ms) : 3620, 3738
. : milestone, 3679,
profiling (2.448 ms) : 2424, 2471
. : milestone, 2448,
tracing (1.9 ms) : 1883, 1916
. : milestone, 1900,
DacapoParameters
See matching parameters
SummaryFound 0 performance improvements and 0 performance regressions! Performance is the same for 12 metrics, 0 unstable metrics. Execution time for biojavagantt
title biojava - execution time [CI 0.99] : candidate=1.62.0-SNAPSHOT~696c0e308c, baseline=1.62.0-SNAPSHOT~42f154d2f6
dateFormat X
axisFormat %s
section baseline
no_agent (15.608 s) : 15608000, 15608000
. : milestone, 15608000,
appsec (14.788 s) : 14788000, 14788000
. : milestone, 14788000,
iast (18.466 s) : 18466000, 18466000
. : milestone, 18466000,
iast_GLOBAL (17.987 s) : 17987000, 17987000
. : milestone, 17987000,
profiling (14.893 s) : 14893000, 14893000
. : milestone, 14893000,
tracing (14.792 s) : 14792000, 14792000
. : milestone, 14792000,
section candidate
no_agent (15.632 s) : 15632000, 15632000
. : milestone, 15632000,
appsec (14.701 s) : 14701000, 14701000
. : milestone, 14701000,
iast (18.581 s) : 18581000, 18581000
. : milestone, 18581000,
iast_GLOBAL (17.944 s) : 17944000, 17944000
. : milestone, 17944000,
profiling (15.397 s) : 15397000, 15397000
. : milestone, 15397000,
tracing (14.972 s) : 14972000, 14972000
. : milestone, 14972000,
Execution time for tomcatgantt
title tomcat - execution time [CI 0.99] : candidate=1.62.0-SNAPSHOT~696c0e308c, baseline=1.62.0-SNAPSHOT~42f154d2f6
dateFormat X
axisFormat %s
section baseline
no_agent (1.489 ms) : 1477, 1500
. : milestone, 1489,
appsec (2.554 ms) : 2499, 2609
. : milestone, 2554,
iast (2.272 ms) : 2203, 2341
. : milestone, 2272,
iast_GLOBAL (2.309 ms) : 2240, 2379
. : milestone, 2309,
profiling (2.117 ms) : 2062, 2172
. : milestone, 2117,
tracing (2.095 ms) : 2041, 2150
. : milestone, 2095,
section candidate
no_agent (1.49 ms) : 1478, 1501
. : milestone, 1490,
appsec (2.538 ms) : 2482, 2593
. : milestone, 2538,
iast (2.269 ms) : 2200, 2338
. : milestone, 2269,
iast_GLOBAL (2.317 ms) : 2247, 2386
. : milestone, 2317,
profiling (2.112 ms) : 2057, 2168
. : milestone, 2112,
tracing (2.085 ms) : 2031, 2138
. : milestone, 2085,
|
What Does This Do
Fix CSI generator by removing the incorrect
.sorted()call from partial-argument index generation.Motivation
AdviceGeneratorImpl.writeStackOperationscalledStream.sorted()without a comparator on a stream ofArgumentSpecificationobjects. BecauseArgumentSpecificationdoes not implementComparable, this throwsClassCastExceptionwhenever an advice method captures two or more arguments from a target method that has strictly more parameters.Additional Notes
The fix is to remove
.sorted()entirely. Theparametersfield inAdviceSpecificationis aTreeMap<Integer, ParameterSpecification>keyed by advice-parameter index, so streaming its values already yields elements in the correct order — the order the advice method declared its parameters. Adding any sort, even one keyed ongetIndex()(the pointcut-side index), would silently produce wrongparameterIndicesarrays for advices that intentionally capture arguments in a different order than they appear in the target method signature.