Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BeanConstraintsDescriptor gives ClassCastException with nested generic types #55

Open
arjanvlek opened this issue Sep 10, 2020 · 0 comments

Comments

@arjanvlek
Copy link
Contributor

For one of our projects, I had the following structure inside one of the persistable entities:

@Transient
private final Map<UUID, List<String>> entityIdsWithSomething = new ConcurrentHashMap<>(); // Only for CSV import of XXX

When accessing the /constraints endpoint, which is provided by BeanConstraintController, the following error is thrown:

10-09-2020 11:14:21.282 ERROR [080-exec-1] l._42.xxx.config.web.errorhandling.ControllerExceptionAdvice:122 Handling request, for [nl._42.jarb.constraint.metadata.BeanConstraintController#describeAll()], resulted in the following exception.
java.lang.ClassCastException: class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to class java.lang.Class (sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl and java.lang.Class are in module java.base of loader 'bootstrap')
	at nl._42.jarb.constraint.metadata.BeanConstraintDescriptor.describeBean(BeanConstraintDescriptor.java:85)
	at nl._42.jarb.constraint.metadata.BeanConstraintService.describe(BeanConstraintService.java:56)
	at nl._42.jarb.constraint.metadata.BeanConstraintService.describeAll(BeanConstraintService.java:30)
	at nl._42.jarb.constraint.metadata.BeanConstraintController.describeAll(BeanConstraintController.java:25)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:626)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)

This seems to be caused by

Class<?> valueType = (Class<?>) getGenericTypes(field)[1];

Which assumes that parameterizedType.getActualTypeArguments() always returns a Class, but this is not the case if another generic type is present (in this case: List<String>).

See https://stackoverflow.com/questions/24829146/classcastexceptionjava-lang-class-cannot-be-cast-to-java-lang-reflect-parameter in which this is explained.

Something should be changed in the BeanConstraintsDescriptor to handle cases like this (or as a quick fix: if the field is annotated with @Transient, then simply skip processing it)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant