From 690ea3e9672b9c237cdfb26c5ccf3f3fdcafa1c5 Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Mon, 20 Sep 2021 13:27:35 +0200 Subject: [PATCH] #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. --- .../server/core/DummyInvocationUtils.java | 8 ++++++++ .../mvc/DummyInvocationUtilsUnitTest.java | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/main/java/org/springframework/hateoas/server/core/DummyInvocationUtils.java b/src/main/java/org/springframework/hateoas/server/core/DummyInvocationUtils.java index 07a10bd7..e05a92f6 100644 --- a/src/main/java/org/springframework/hateoas/server/core/DummyInvocationUtils.java +++ b/src/main/java/org/springframework/hateoas/server/core/DummyInvocationUtils.java @@ -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 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); diff --git a/src/test/java/org/springframework/hateoas/server/mvc/DummyInvocationUtilsUnitTest.java b/src/test/java/org/springframework/hateoas/server/mvc/DummyInvocationUtilsUnitTest.java index c654d6a9..caa932f2 100755 --- a/src/test/java/org/springframework/hateoas/server/mvc/DummyInvocationUtilsUnitTest.java +++ b/src/test/java/org/springframework/hateoas/server/mvc/DummyInvocationUtilsUnitTest.java @@ -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 someOtherMethod(@PathVariable(name = "otherName") Long id) { return new ResponseEntity<>(HttpStatus.OK); } + + Object methodReturningObject() { + return Void.class; + } } }