Skip to content

Mis-proxying of Mockito mock and poor diagnostics for type mismatch on proxy injection [SPR-14478] #19047

Closed
@spring-projects-issues

Description

@spring-projects-issues

Andy Wilkinson opened SPR-14478 and commented

There's a small sample application in the referenced Spring Boot issue that reproduces the problem.

There's a Mockito-created mock bean in the context. Due to @EnableAsync this bean is proxied using a JDK proxy (proxyTarget class is false). An attempt is then made to autowire the mocked bean into another class. This fails because the JDK proxy is for a Mockito interface. This in itself could perhaps be considered a problem as the proxy has the wrong form.

The proxy is considered to be a viable candidate for autowiring due to predictBeanType on AbstractAutowireCapableBeanFactory returning the type of the underlying bean, ignoring the proxying that'll be performed by AsyncAnnotationBeanPostProcessor. Ultimately this results in a BeanInstantiationException that doesn't shed much light on what's actually gone wrong:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.example.TestController]: Illegal arguments for constructor; nested exception is java.lang.IllegalArgumentException: argument type mismatch
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:156) ~[spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:122) ~[spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:271) ~[spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
	... 41 common frames omitted
Caused by: java.lang.IllegalArgumentException: argument type mismatch
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_60]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_60]
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_60]
	at java.lang.reflect.Constructor.newInstance(Constructor.java:422) ~[na:1.8.0_60]
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147) ~[spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
	... 43 common frames omitted

There are three areas where things are going wrong, each probably a knock-on effect of the previous one:

  1. The proxy creation goes wrong and creates a proxy for a Mockito interface rather than anything that was actually implemented by the underlying bean
  2. The type prediction is wrong and returns a type of which the proxied bean is not an instance
  3. The diagnostics for the resulting IllegalArgumentException don't reveal anything about the arguments that were passed to the constructor and their types so you can't immediately see why it might have failed.

Affects: 4.3.1

Reference URL: spring-projects/spring-boot#6405

Issue Links:

Referenced from: commits 0e3f0bd, 503d65d

0 votes, 6 watchers

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions