Skip to content

Commit a0763d1

Browse files
committed
Merge branch '6.2.x'
2 parents 30a7f7b + 86b2617 commit a0763d1

File tree

8 files changed

+74
-63
lines changed

8 files changed

+74
-63
lines changed

spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java

+11-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -237,7 +237,7 @@ public void setThrowingName(@Nullable String throwingName) {
237237

238238
try {
239239
int algorithmicStep = STEP_JOIN_POINT_BINDING;
240-
while ((this.numberOfRemainingUnboundArguments > 0) && algorithmicStep < STEP_FINISHED) {
240+
while (this.numberOfRemainingUnboundArguments > 0 && algorithmicStep < STEP_FINISHED) {
241241
switch (algorithmicStep++) {
242242
case STEP_JOIN_POINT_BINDING -> {
243243
if (!maybeBindThisJoinPoint()) {
@@ -368,7 +368,8 @@ private void maybeBindReturningVariable() {
368368
if (this.returningName != null) {
369369
if (this.numberOfRemainingUnboundArguments > 1) {
370370
throw new AmbiguousBindingException("Binding of returning parameter '" + this.returningName +
371-
"' is ambiguous: there are " + this.numberOfRemainingUnboundArguments + " candidates.");
371+
"' is ambiguous: there are " + this.numberOfRemainingUnboundArguments + " candidates. " +
372+
"Consider compiling with -parameters in order to make declared parameter names available.");
372373
}
373374

374375
// We're all set... find the unbound parameter, and bind it.
@@ -479,8 +480,8 @@ private void maybeExtractVariableNamesFromArgs(@Nullable String argsSpec, List<S
479480
*/
480481
private void maybeBindThisOrTargetOrArgsFromPointcutExpression() {
481482
if (this.numberOfRemainingUnboundArguments > 1) {
482-
throw new AmbiguousBindingException("Still " + this.numberOfRemainingUnboundArguments
483-
+ " unbound args at this()/target()/args() binding stage, with no way to determine between them");
483+
throw new AmbiguousBindingException("Still " + this.numberOfRemainingUnboundArguments +
484+
" unbound args at this()/target()/args() binding stage, with no way to determine between them");
484485
}
485486

486487
List<String> varNames = new ArrayList<>();
@@ -529,8 +530,8 @@ else if (varNames.size() == 1) {
529530

530531
private void maybeBindReferencePointcutParameter() {
531532
if (this.numberOfRemainingUnboundArguments > 1) {
532-
throw new AmbiguousBindingException("Still " + this.numberOfRemainingUnboundArguments
533-
+ " unbound args at reference pointcut binding stage, with no way to determine between them");
533+
throw new AmbiguousBindingException("Still " + this.numberOfRemainingUnboundArguments +
534+
" unbound args at reference pointcut binding stage, with no way to determine between them");
534535
}
535536

536537
List<String> varNames = new ArrayList<>();
@@ -735,7 +736,9 @@ private void findAndBind(Class<?> argumentType, String varName) {
735736
* Simple record to hold the extracted text from a pointcut body, together
736737
* with the number of tokens consumed in extracting it.
737738
*/
738-
private record PointcutBody(int numTokensConsumed, @Nullable String text) {}
739+
private record PointcutBody(int numTokensConsumed, @Nullable String text) {
740+
}
741+
739742

740743
/**
741744
* Thrown in response to an ambiguous binding being detected when

spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactoryTests.java

+30-33
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -203,7 +203,6 @@ void perThisAspect() throws Exception {
203203
itb.getSpouse();
204204

205205
assertThat(maaif.isMaterialized()).isTrue();
206-
207206
assertThat(imapa.getDeclaredPointcut().getMethodMatcher().matches(TestBean.class.getMethod("getAge"), null)).isTrue();
208207

209208
assertThat(itb.getAge()).as("Around advice must apply").isEqualTo(0);
@@ -301,7 +300,7 @@ void bindingWithSingleArg() {
301300
void bindingWithMultipleArgsDifferentlyOrdered() {
302301
ManyValuedArgs target = new ManyValuedArgs();
303302
ManyValuedArgs mva = createProxy(target, ManyValuedArgs.class,
304-
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new ManyValuedArgs(), "someBean")));
303+
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new ManyValuedArgs(), "someBean")));
305304

306305
String a = "a";
307306
int b = 12;
@@ -320,7 +319,7 @@ void introductionOnTargetNotImplementingInterface() {
320319
NotLockable notLockableTarget = new NotLockable();
321320
assertThat(notLockableTarget).isNotInstanceOf(Lockable.class);
322321
NotLockable notLockable1 = createProxy(notLockableTarget, NotLockable.class,
323-
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")));
322+
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")));
324323
assertThat(notLockable1).isInstanceOf(Lockable.class);
325324
Lockable lockable = (Lockable) notLockable1;
326325
assertThat(lockable.locked()).isFalse();
@@ -329,7 +328,7 @@ void introductionOnTargetNotImplementingInterface() {
329328

330329
NotLockable notLockable2Target = new NotLockable();
331330
NotLockable notLockable2 = createProxy(notLockable2Target, NotLockable.class,
332-
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")));
331+
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")));
333332
assertThat(notLockable2).isInstanceOf(Lockable.class);
334333
Lockable lockable2 = (Lockable) notLockable2;
335334
assertThat(lockable2.locked()).isFalse();
@@ -343,20 +342,19 @@ void introductionOnTargetNotImplementingInterface() {
343342
void introductionAdvisorExcludedFromTargetImplementingInterface() {
344343
assertThat(AopUtils.findAdvisorsThatCanApply(
345344
getAdvisorFactory().getAdvisors(
346-
aspectInstanceFactory(new MakeLockable(), "someBean")),
345+
aspectInstanceFactory(new MakeLockable(), "someBean")),
347346
CannotBeUnlocked.class)).isEmpty();
348347
assertThat(AopUtils.findAdvisorsThatCanApply(getAdvisorFactory().getAdvisors(
349-
aspectInstanceFactory(new MakeLockable(),"someBean")), NotLockable.class)).hasSize(2);
348+
aspectInstanceFactory(new MakeLockable(),"someBean")), NotLockable.class)).hasSize(2);
350349
}
351350

352351
@Test
353352
void introductionOnTargetImplementingInterface() {
354353
CannotBeUnlocked target = new CannotBeUnlocked();
355354
Lockable proxy = createProxy(target, CannotBeUnlocked.class,
356-
// Ensure that we exclude
357355
AopUtils.findAdvisorsThatCanApply(
358-
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")),
359-
CannotBeUnlocked.class));
356+
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")),
357+
CannotBeUnlocked.class));
360358
assertThat(proxy).isInstanceOf(Lockable.class);
361359
Lockable lockable = proxy;
362360
assertThat(lockable.locked()).as("Already locked").isTrue();
@@ -370,16 +368,16 @@ void introductionOnTargetExcludedByTypePattern() {
370368
ArrayList<Object> target = new ArrayList<>();
371369
List<?> proxy = createProxy(target, List.class,
372370
AopUtils.findAdvisorsThatCanApply(
373-
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")),
374-
List.class));
371+
getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")),
372+
List.class));
375373
assertThat(proxy).as("Type pattern must have excluded mixin").isNotInstanceOf(Lockable.class);
376374
}
377375

378376
@Test
379377
void introductionBasedOnAnnotationMatch() { // gh-9980
380378
AnnotatedTarget target = new AnnotatedTargetImpl();
381379
List<Advisor> advisors = getAdvisorFactory().getAdvisors(
382-
aspectInstanceFactory(new MakeAnnotatedTypeModifiable(), "someBean"));
380+
aspectInstanceFactory(new MakeAnnotatedTypeModifiable(), "someBean"));
383381
Object proxy = createProxy(target, AnnotatedTarget.class, advisors);
384382
assertThat(proxy).isInstanceOf(Lockable.class);
385383
Lockable lockable = (Lockable) proxy;
@@ -393,9 +391,9 @@ void introductionWithArgumentBinding() {
393391
TestBean target = new TestBean();
394392

395393
List<Advisor> advisors = getAdvisorFactory().getAdvisors(
396-
aspectInstanceFactory(new MakeITestBeanModifiable(), "someBean"));
394+
aspectInstanceFactory(new MakeITestBeanModifiable(), "someBean"));
397395
advisors.addAll(getAdvisorFactory().getAdvisors(
398-
aspectInstanceFactory(new MakeLockable(), "someBean")));
396+
aspectInstanceFactory(new MakeLockable(), "someBean")));
399397

400398
Modifiable modifiable = (Modifiable) createProxy(target, ITestBean.class, advisors);
401399
assertThat(modifiable).isInstanceOf(Modifiable.class);
@@ -426,7 +424,7 @@ void aspectMethodThrowsExceptionLegalOnSignature() {
426424
TestBean target = new TestBean();
427425
UnsupportedOperationException expectedException = new UnsupportedOperationException();
428426
List<Advisor> advisors = getAdvisorFactory().getAdvisors(
429-
aspectInstanceFactory(new ExceptionThrowingAspect(expectedException), "someBean"));
427+
aspectInstanceFactory(new ExceptionThrowingAspect(expectedException), "someBean"));
430428
assertThat(advisors).as("One advice method was found").hasSize(1);
431429
ITestBean itb = createProxy(target, ITestBean.class, advisors);
432430
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(itb::getAge);
@@ -439,20 +437,20 @@ void aspectMethodThrowsExceptionIllegalOnSignature() {
439437
TestBean target = new TestBean();
440438
RemoteException expectedException = new RemoteException();
441439
List<Advisor> advisors = getAdvisorFactory().getAdvisors(
442-
aspectInstanceFactory(new ExceptionThrowingAspect(expectedException), "someBean"));
440+
aspectInstanceFactory(new ExceptionThrowingAspect(expectedException), "someBean"));
443441
assertThat(advisors).as("One advice method was found").hasSize(1);
444442
ITestBean itb = createProxy(target, ITestBean.class, advisors);
445443
assertThatExceptionOfType(UndeclaredThrowableException.class)
446-
.isThrownBy(itb::getAge)
447-
.withCause(expectedException);
444+
.isThrownBy(itb::getAge)
445+
.withCause(expectedException);
448446
}
449447

450448
@Test
451449
void twoAdvicesOnOneAspect() {
452450
TestBean target = new TestBean();
453451
TwoAdviceAspect twoAdviceAspect = new TwoAdviceAspect();
454452
List<Advisor> advisors = getAdvisorFactory().getAdvisors(
455-
aspectInstanceFactory(twoAdviceAspect, "someBean"));
453+
aspectInstanceFactory(twoAdviceAspect, "someBean"));
456454
assertThat(advisors).as("Two advice methods found").hasSize(2);
457455
ITestBean itb = createProxy(target, ITestBean.class, advisors);
458456
itb.setName("");
@@ -466,7 +464,7 @@ void twoAdvicesOnOneAspect() {
466464
void afterAdviceTypes() throws Exception {
467465
InvocationTrackingAspect aspect = new InvocationTrackingAspect();
468466
List<Advisor> advisors = getAdvisorFactory().getAdvisors(
469-
aspectInstanceFactory(aspect, "exceptionHandlingAspect"));
467+
aspectInstanceFactory(aspect, "exceptionHandlingAspect"));
470468
Echo echo = createProxy(new Echo(), Echo.class, advisors);
471469

472470
assertThat(aspect.invocations).isEmpty();
@@ -475,7 +473,7 @@ void afterAdviceTypes() throws Exception {
475473

476474
aspect.invocations.clear();
477475
assertThatExceptionOfType(FileNotFoundException.class)
478-
.isThrownBy(() -> echo.echo(new FileNotFoundException()));
476+
.isThrownBy(() -> echo.echo(new FileNotFoundException()));
479477
assertThat(aspect.invocations).containsExactly("around - start", "before", "after throwing", "after", "around - end");
480478
}
481479

@@ -487,7 +485,6 @@ void nonAbstractParentAspect() {
487485
assertThat(Modifier.isAbstract(aspect.getClass().getSuperclass().getModifiers())).isFalse();
488486

489487
List<Advisor> advisors = getAdvisorFactory().getAdvisors(aspectInstanceFactory(aspect, "incrementingAspect"));
490-
491488
ITestBean proxy = createProxy(new TestBean("Jane", 42), ITestBean.class, advisors);
492489
assertThat(proxy.getAge()).isEqualTo(86); // (42 + 1) * 2
493490
}
@@ -812,19 +809,19 @@ void before() {
812809
invocations.add("before");
813810
}
814811

815-
@AfterReturning("echo()")
816-
void afterReturning() {
817-
invocations.add("after returning");
812+
@After("echo()")
813+
void after() {
814+
invocations.add("after");
818815
}
819816

820-
@AfterThrowing("echo()")
821-
void afterThrowing() {
822-
invocations.add("after throwing");
817+
@AfterReturning(pointcut = "this(target) && execution(* echo(*))", returning = "returnValue")
818+
void afterReturning(JoinPoint joinPoint, Echo target, Object returnValue) {
819+
invocations.add("after returning");
823820
}
824821

825-
@After("echo()")
826-
void after() {
827-
invocations.add("after");
822+
@AfterThrowing(pointcut = "this(target) && execution(* echo(*))", throwing = "exception")
823+
void afterThrowing(JoinPoint joinPoint, Echo target, Throwable exception) {
824+
invocations.add("after throwing");
828825
}
829826
}
830827

@@ -967,7 +964,7 @@ private Method getGetterFromSetter(Method setter) {
967964
class MakeITestBeanModifiable extends AbstractMakeModifiable {
968965

969966
@DeclareParents(value = "org.springframework.beans.testfixture.beans.ITestBean+",
970-
defaultImpl=ModifiableImpl.class)
967+
defaultImpl = ModifiableImpl.class)
971968
static MutableModifiable mixin;
972969

973970
}

spring-core/src/main/java/org/springframework/asm/ClassReader.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ public ClassReader(
195195
this.b = classFileBuffer;
196196
// Check the class' major_version. This field is after the magic and minor_version fields, which
197197
// use 4 and 2 bytes respectively.
198-
if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V24) {
198+
if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V25) {
199199
throw new IllegalArgumentException(
200200
"Unsupported class file major version " + readShort(classFileOffset + 6));
201201
}

spring-core/src/main/java/org/springframework/asm/MethodVisitor.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ public void visitTableSwitchInsn(
594594
* Visits a LOOKUPSWITCH instruction.
595595
*
596596
* @param dflt beginning of the default handler block.
597-
* @param keys the values of the keys.
597+
* @param keys the values of the keys. Keys must be sorted in increasing order.
598598
* @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the
599599
* handler block for the {@code keys[i]} key.
600600
*/

spring-core/src/main/java/org/springframework/asm/Opcodes.java

+1
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ public interface Opcodes {
289289
int V22 = 0 << 16 | 66;
290290
int V23 = 0 << 16 | 67;
291291
int V24 = 0 << 16 | 68;
292+
int V25 = 0 << 16 | 69;
292293

293294
/**
294295
* Version flag indicating that the class is using 'preview' features.

spring-core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java

+11-6
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public boolean exists() {
5656
// Try a URL connection content-length header
5757
URLConnection con = url.openConnection();
5858
customizeConnection(con);
59+
5960
HttpURLConnection httpCon = (con instanceof HttpURLConnection huc ? huc : null);
6061
if (httpCon != null) {
6162
httpCon.setRequestMethod("HEAD");
@@ -81,12 +82,16 @@ else if (code == HttpURLConnection.HTTP_NOT_FOUND) {
8182
}
8283
}
8384
}
84-
// Check content-length entry but not for JarURLConnection where
85-
// this would open the jar file but effectively never close it ->
86-
// for jar entries, always fall back to stream existence instead.
87-
if (!(con instanceof JarURLConnection) && con.getContentLengthLong() > 0) {
85+
86+
if (con instanceof JarURLConnection jarCon) {
87+
// For JarURLConnection, do not check content-length but rather the
88+
// existence of the entry (or the jar root in case of no entryName).
89+
return (jarCon.getEntryName() == null || jarCon.getJarEntry() != null);
90+
}
91+
else if (con.getContentLengthLong() > 0) {
8892
return true;
8993
}
94+
9095
if (httpCon != null) {
9196
// No HTTP OK status, and no content-length header: give up
9297
httpCon.disconnect();
@@ -346,8 +351,8 @@ public long lastModified() throws IOException {
346351
*/
347352
protected void customizeConnection(URLConnection con) throws IOException {
348353
ResourceUtils.useCachesIfNecessary(con);
349-
if (con instanceof HttpURLConnection httpConn) {
350-
customizeConnection(httpConn);
354+
if (con instanceof HttpURLConnection httpCon) {
355+
customizeConnection(httpCon);
351356
}
352357
}
353358

spring-core/src/main/java/org/springframework/core/io/UrlResource.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -233,8 +233,8 @@ public InputStream getInputStream() throws IOException {
233233
}
234234
catch (IOException ex) {
235235
// Close the HTTP connection (if applicable).
236-
if (con instanceof HttpURLConnection httpConn) {
237-
httpConn.disconnect();
236+
if (con instanceof HttpURLConnection httpCon) {
237+
httpCon.disconnect();
238238
}
239239
throw ex;
240240
}

0 commit comments

Comments
 (0)