Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resteasy-Spring: incorrect app instance loaded during tests with multiple running instances

Short summary of issue:

I wrote a simple REST HTTP interface, built with Spring Boot, which returns a simple text response when calling GET /app, based on the implementation of the ClientInterface, of which there are 2. The REST capabilities are implemented using JAX-RS, provided by resteasy through the RestEasy-SpringBoot library.

I have also written 3 tests, of which the 3rd is failing because the response is coming from the second implementation of ClientInterface instead of the first implementation, because (I assume) Resteasy is mixing up the app instances, and hence the incorrect Spring Application context is loaded, with the incorrect beans.

NOTE: you can find the sample application here, which includes documentation as well

Please take a look at the source code to get a clear picture. It would occupy too much space to paste in the code as well.

Further details:

There are 2 implementations of ClientInterface which provide the response given by the REST resource. They are toggled using the client-impl-two profile. If the profile is not present, the first implementation is used, if it is present, the second is used.

The first and third tests expect the response from the first implementation, and the second test expects the response from the seconds implementation, because it is using the client-two-impl profile.

When I run the tests using the JUnit integration from IntelliJ, the third one fails: enter image description here enter image description here

You'll notice the tests are named such that it enforces a certain execution order, which is relevant because the third test only fails if it is executed AFTER the second one. And it's failing because it got the response from the second ClientInterface implementation, even though the third test is NOT using the client-impl-two profile.

What I have done/discovered so far:

  • sometimes, running ./mvnw clean test also has the same error results, but I have been unable to provide a reproducible example
  • the Spring Application context is correctly loaded by Spring/Spring Boot
  • Spring Boot correctly injects the port number, and the rest client in the tests always call the REST instance they are supposed to
  • it is only when Resteasy takes over the request, that it somehow loads up the incorrect instance of the application, and hence the incorrect Spring Application context is used, which is why it's giving the incorrect response
    • this I figured out by keeping a breakpoint in SpringResourceFactory.createResource() where it's just querynig the beanFactory for the resource bean, and calling beanFactory.getBean(ClientInterface.class) to see which implementation comes up, and it was the incorrect one for the third test
  • during the tests, there is more than one instance of the application running, each on it's own port, which I assume has something to do with the issue
  • there is another branch, jersey-instead-of-resteasy in which Jersey is used as the JAX-RS implementation, and where the tests are successful no matter if they are run with IntelliJ or with Maven
  • there is a DebugFilter with which I check what the Spring Application context looks like before the request is taken over by the Resteasy servlet, and it is always the correct one (the correct implementation of ClientInterface is loaded), no matter how test is executed
    • it's only when running the third test, and when the request reaches Resteasy, that the incorrect app instance is loaded, as noted in one of the above points

Based on the points above, I have a strong suspicion Resteasy might be the issue.

Any help is greatly appreciated.

like image 335
Gabriel Ruiu Avatar asked Oct 30 '22 13:10

Gabriel Ruiu


1 Answers

I've debugged this a bit and I believe the failure is caused by a bug in the resteasy-spring-boot-starter. I've just created an issue on github and provided a PR [2] that fixes it and make your test pass. I'm also commenting on [3]. Kudos for the great description and reproducer.

  1. https://github.com/paypal/resteasy-spring-boot/issues/51
  2. https://github.com/paypal/resteasy-spring-boot/pull/52
  3. https://issues.jboss.org/browse/RESTEASY-1595
like image 97
Alessio Soldano Avatar answered Nov 18 '22 07:11

Alessio Soldano