From cc8c852c2bd59d87afb90fe79b850161b23acf26 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 12 Jun 2023 11:33:54 +0200 Subject: [PATCH 1/2] Specific check for parent of MethodInvocationInfo ClassLoader See gh-30389 --- .../annotation/MvcUriComponentsBuilder.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java index 46c3ab1543..5086cf055e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java @@ -780,11 +780,24 @@ public class MvcUriComponentsBuilder { else if (controllerType.isInterface()) { ClassLoader classLoader = controllerType.getClassLoader(); - if (classLoader == null || classLoader.getParent() == null) { - // JDK interface type from bootstrap loader or platform loader -> - // use higher-level loader which can see Spring infrastructure classes + if (classLoader == null) { + // JDK bootstrap loader -> use MethodInvocationInfo ClassLoader instead. classLoader = MethodInvocationInfo.class.getClassLoader(); } + else if (classLoader.getParent() == null) { + // Potentially the JDK platform loader on JDK 9+ + ClassLoader miiClassLoader = MethodInvocationInfo.class.getClassLoader(); + ClassLoader miiParent = miiClassLoader.getParent(); + while (miiParent != null) { + if (classLoader == miiParent) { + // Suggested ClassLoader is ancestor of MethodInvocationInfo ClassLoader + // -> use MethodInvocationInfo ClassLoader itself instead. + classLoader = miiClassLoader; + break; + } + miiParent = miiParent.getParent(); + } + } Class[] ifcs = new Class[] {controllerType, MethodInvocationInfo.class}; return (T) Proxy.newProxyInstance(classLoader, ifcs, interceptor); } From f8c8873c99e8064d9ba6b1c8d86217f019d46daa Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 12 Jun 2023 12:55:09 +0200 Subject: [PATCH 2/2] Document which @Scheduled attributes support SpEL expressions Closes gh-29290 --- .../scheduling/annotation/Scheduled.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java index 1b4cca0778..a202e7846b 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -122,9 +122,12 @@ public @interface Scheduled { * last invocation and the start of the next. *

The time unit is milliseconds by default but can be overridden via * {@link #timeUnit}. + *

This attribute variant supports Spring-style "${...}" placeholders + * as well as SpEL expressions. * @return the delay as a String value — for example, a placeholder * or a {@link java.time.Duration#parse java.time.Duration} compliant value * @since 3.2.2 + * @see #fixedDelay() */ String fixedDelayString() default ""; @@ -140,9 +143,12 @@ public @interface Scheduled { * Execute the annotated method with a fixed period between invocations. *

The time unit is milliseconds by default but can be overridden via * {@link #timeUnit}. + *

This attribute variant supports Spring-style "${...}" placeholders + * as well as SpEL expressions. * @return the period as a String value — for example, a placeholder * or a {@link java.time.Duration#parse java.time.Duration} compliant value * @since 3.2.2 + * @see #fixedRate() */ String fixedRateString() default ""; @@ -161,9 +167,12 @@ public @interface Scheduled { * {@link #fixedRate} or {@link #fixedDelay} task. *

The time unit is milliseconds by default but can be overridden via * {@link #timeUnit}. + *

This attribute variant supports Spring-style "${...}" placeholders + * as well as SpEL expressions. * @return the initial delay as a String value — for example, a placeholder * or a {@link java.time.Duration#parse java.time.Duration} compliant value * @since 3.2.2 + * @see #initialDelay() */ String initialDelayString() default "";