Skip to content

Commit

Permalink
Ensure methods declared in Object can be invoked on a JDK proxy in SpEL
Browse files Browse the repository at this point in the history
This commit ensures that methods declared in java.lang.Object (such as
toString() can be invoked on a JDK proxy instance in a SpEL expression.

Closes gh-25316
  • Loading branch information
mrcoffee77 authored and sbrannen committed Mar 15, 2023
1 parent 30601a5 commit 36682b7
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,7 @@
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;

import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.MethodParameter;
Expand Down Expand Up @@ -266,7 +260,13 @@ else if (Proxy.isProxyClass(type)) {
* @since 3.1.1
*/
protected Method[] getMethods(Class<?> type) {
return type.getMethods();
Set<Method> methods=new HashSet<>();
methods.addAll(Arrays.asList(type.getMethods()));
//Add all methods of Object to have methods like toString on Proxy-Objects
methods.addAll(Arrays.asList(Object.class.getMethods()));

Method[] methods1 = methods.toArray(new Method[0]);
return methods1;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,21 @@

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

import org.junit.jupiter.api.Test;

import org.springframework.core.convert.TypeDescriptor;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ParseException;
import org.springframework.expression.PropertyAccessor;
import org.springframework.expression.TypedValue;
import org.springframework.expression.*;
import org.springframework.expression.spel.AbstractExpressionTests;
import org.springframework.expression.spel.SpelUtilities;
import org.springframework.expression.spel.standard.SpelExpression;
import org.springframework.expression.spel.support.ReflectionHelper.ArgumentsMatchKind;
import org.springframework.util.Assert;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
Expand Down Expand Up @@ -364,6 +364,19 @@ public void testOptimalReflectivePropertyAccessor() throws Exception {
field.write(ctx, tester, "field", null));
}

@Test
void testReflectiveMethodResolver() throws AccessException {
MethodResolver resolver=new ReflectiveMethodResolver();
StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
Object obj= Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class<?>[]{Runnable.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return null;
}
});
MethodExecutor mexec=resolver.resolve(evaluationContext,obj,"toString",new ArrayList<>());
Assert.notNull(mexec,"MethodExecutor should not be empty.");
}

/**
* Used to validate the match returned from a compareArguments call.
Expand Down

0 comments on commit 36682b7

Please sign in to comment.