Description
The InvocationRecordingMethodInterceptor
overflows the stack when using non-statically compiled Groovy. The problem exists because the interceptor is returning a new proxy with each invocation, and Groovy's method dispatching workflow inspects the metaClass of each object to determine the appropriate call site to use.
Simple example demonstrating the issue:
@Configuration
@ComponentScan
@EnableAutoConfiguration
@EnableJpaRepositories
@EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL)
class Main {
static void main(_) {
SpringApplication.run this, [] as String[]
}
}
@javax.persistence.Entity
class Foo {
@javax.persistence.Id
Long id
String name
}
@Repository
interface Foos extends CrudRepository<Foo, Long> {
}
@RestController
@RequestMapping("/foo")
class FooController {
@Autowired
Foos foos
@RequestMapping(method = GET)
Resources<Foo> list() {
def foos = foos.findAll()
def resources = new Resources<>(foos)
if (resources) {
resources.add(linkTo(methodOn(this.class).list()).withSelfRel())
}
resources
}
}
A "fix" would be to statically compile the FooController
, but this means that we can't use the metaClass:
@CompileStatic
@RestController
@RequestMapping("/foo")
class FooController {
...
}
I'm not sure what the best solution to this is... It seems like there should be a way to ascertain if the current invocation is identical to the last invocation, though I'm not sure how that could be determined given a new proxy object is returned each time. Probably need help from @melix on this one.