#1646 - 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 c2fca8be01
commit be6615c434
2 changed files with 34 additions and 1 deletions

View File

@@ -144,13 +144,24 @@ public class DummyInvocationUtils {
*/
@Nullable
public static LastInvocationAware getLastInvocationAware(Object source) {
return (LastInvocationAware) ((Advised) source).getAdvisors()[0].getAdvice();
if (InvocationRecordingMethodInterceptor.class.isInstance(source)) {
return LastInvocationAware.class.cast(source);
}
return (LastInvocationAware) (Advised.class.isInstance(source)
? ((Advised) source).getAdvisors()[0].getAdvice()
: source);
}
@SuppressWarnings("unchecked")
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);
@@ -207,6 +218,11 @@ public class DummyInvocationUtils {
return result;
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "DummyInvocationUtils.CacheKey(type=" + this.type + ", arguments=" + Arrays.deepToString(this.arguments)

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;
}
}
}