#1638 - Avoid trying to proxy Object for controller method dummy invocations.

On JDK 17, trying to proxy Object doesn't work anymore. We now simply return the interceptor that would've been applied to the proxy directly and detect that properly in requests to extract the LastInvocationAware instance.
This commit is contained in:
Oliver Drotbohm
2021-09-20 13:27:35 +02:00
parent 2fcad81d6c
commit 690ea3e967
2 changed files with 25 additions and 0 deletions

View File

@@ -145,6 +145,10 @@ public class DummyInvocationUtils {
@Nullable
public static LastInvocationAware getLastInvocationAware(Object source) {
if (InvocationRecordingMethodInterceptor.class.isInstance(source)) {
return LastInvocationAware.class.cast(source);
}
return (LastInvocationAware) (Advised.class.isInstance(source)
? ((Advised) source).getAdvisors()[0].getAdvice()
: source);
@@ -179,6 +183,10 @@ public class DummyInvocationUtils {
private static <T> T getProxyWithInterceptor(Class<?> type, InvocationRecordingMethodInterceptor interceptor,
ClassLoader classLoader) {
if (type.equals(Object.class)) {
return (T) interceptor;
}
ProxyFactory factory = new ProxyFactory();
factory.addAdvice(interceptor);
factory.addInterface(LastInvocationAware.class);

View File

@@ -19,8 +19,11 @@ import static org.assertj.core.api.Assertions.*;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;
import org.junit.jupiter.api.Test;
import org.springframework.aop.framework.Advised;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.TestUtils;
import org.springframework.hateoas.server.core.DummyInvocationUtils;
import org.springframework.hateoas.server.core.LastInvocationAware;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@@ -48,6 +51,16 @@ class DummyInvocationUtilsUnitTest extends TestUtils {
assertThat(link.getHref()).isEqualTo("http://localhost/sample/2/bar");
}
@Test // #1638
void doesNotTryToProxyObject() {
Object result = methodOn(SampleController.class).methodReturningObject();
assertThat(result).isInstanceOf(LastInvocationAware.class);
assertThat(result).isNotInstanceOf(Advised.class);
assertThat(DummyInvocationUtils.getLastInvocationAware(result)).isSameAs(result);
}
@RequestMapping("/sample")
static class SampleController {
@@ -60,5 +73,9 @@ class DummyInvocationUtilsUnitTest extends TestUtils {
HttpEntity<Void> someOtherMethod(@PathVariable(name = "otherName") Long id) {
return new ResponseEntity<>(HttpStatus.OK);
}
Object methodReturningObject() {
return Void.class;
}
}
}