Skip to content

MvcUriComponentsBuilder.fromMethodCall breaks for controller with CharSequence return type #30210

@hinnerkoetting

Description

@hinnerkoetting

I am currently trying to upgrade to upgrade to Spring 5.3.26 (from 5.3.26, via Spring Boot 2.7.10) and encounter an error when using MvcUriComponentsBuilder.fromMethodCall for a controller that returns CharSequence. I believe this error is caused by this change: #29913

Stacktrace

Caused by: java.lang.IllegalStateException: Failed to create proxy for controller method return type: public java.lang.CharSequence com.example.OurController.show(javax.servlet.http.HttpServletRequest,org.springframework.ui.Model,java.lang.String,java.lang.String,java.lang.Boolean,org.springframework.security.core.userdetails.UserDetails)
	at org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder$ControllerMethodInvocationInterceptor.intercept(MvcUriComponentsBuilder.java:737)
	at com.example.OurController$$EnhancerBySpringCGLIB$$b5e40016.show(<generated>)
Caused by: java.lang.IllegalArgumentException: org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder$MethodInvocationInfo referenced from a method is not visible from class loader
	at java.base/java.lang.reflect.Proxy$ProxyBuilder.ensureVisible(Proxy.java:883)
	at java.base/java.lang.reflect.Proxy$ProxyBuilder.validateProxyInterfaces(Proxy.java:721)
	at java.base/java.lang.reflect.Proxy$ProxyBuilder.<init>(Proxy.java:648)
	at java.base/java.lang.reflect.Proxy.lambda$getProxyConstructor$1(Proxy.java:440)
	at java.base/jdk.internal.loader.AbstractClassLoaderValue$Memoizer.get(AbstractClassLoaderValue.java:329)
	at java.base/jdk.internal.loader.AbstractClassLoaderValue.computeIfAbsent(AbstractClassLoaderValue.java:205)
	at java.base/java.lang.reflect.Proxy.getProxyConstructor(Proxy.java:438)
	at java.base/java.lang.reflect.Proxy.newProxyInstance(Proxy.java:1037)

Our code

@Controller
public class OurController {
  public CharSequence show(...) {
     return "some-view";
  }
}
...
public class OurService {
  public String getUrl() {
    return MvcUriComponentsBuilder
                .fromMethodCall(on(OurController.class).show(...)
                .build()
                .encode();
  }
}

After change #29913 MvcUriComponentsBuilder uses the classloader of the return type (in our case CharSequence) which returns null which causes the issue above.

Workaround

It's possible to return ModelAndView instead of CharSequence to fix this issue.

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)status: backportedAn issue that has been backported to maintenance branchestype: regressionA bug that is also a regression

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions