@@ -14,9 +14,11 @@ import org.utbot.instrumentation.instrumentation.Instrumentation
1414import org.utbot.instrumentation.instrumentation.execution.mock.SpringInstrumentationContext
1515import org.utbot.instrumentation.instrumentation.execution.phases.ModelConstructionPhase
1616import org.utbot.instrumentation.process.HandlerClassesLoader
17+ import org.utbot.spring.api.context.ContextWrapper
18+ import org.utbot.spring.api.instantiator.InstantiationSettings
19+ import org.utbot.spring.api.instantiator.ApplicationInstantiatorFacade
1720import org.utbot.spring.api.repositoryWrapper.RepositoryInteraction
1821import java.security.ProtectionDomain
19- import kotlin.random.Random
2022
2123/* *
2224 * UtExecutionInstrumentation wrapper that is aware of Spring config and initialises Spring context
@@ -25,7 +27,7 @@ class SpringUtExecutionInstrumentation(
2527 private val instrumentation : UtExecutionInstrumentation ,
2628 private val springConfig : String
2729) : Instrumentation<UtConcreteExecutionResult> by instrumentation {
28- private lateinit var springContext: Any
30+ private lateinit var springContext: ContextWrapper
2931
3032 companion object {
3133 private val logger = getLogger<SpringUtExecutionInstrumentation >()
@@ -52,22 +54,23 @@ class SpringUtExecutionInstrumentation(
5254 val classLoader = utContext.classLoader
5355 Thread .currentThread().contextClassLoader = classLoader
5456
55- val primarySources = arrayOf(
56- classLoader.loadClass(springConfig),
57- classLoader.loadClass(" org.utbot.spring.repositoryWrapper.RepositoryWrapperConfiguration" )
57+ val instantiationSettings = InstantiationSettings (
58+ configurationClasses = arrayOf(
59+ classLoader.loadClass(springConfig),
60+ classLoader.loadClass(" org.utbot.spring.repositoryWrapper.RepositoryWrapperConfiguration" )
61+ ),
62+ profileExpression = null ,
5863 )
5964
60- // Setting server.port value to 0 means given Spring to select any appropriate port itself.
61- // See https://stackoverflow.com/questions/21083170/how-to-configure-port-for-a-spring-boot-application
62- val args = arrayOf(" --server.port=0" )
63-
64- // TODO if we don't have SpringBoot just create ApplicationContext here, reuse code from utbot-spring-analyzer
65- // TODO recreate context/app every time whenever we change method under test
66- val springAppClass =
67- classLoader.loadClass(" org.springframework.boot.SpringApplication" )
68- springContext = springAppClass
69- .getMethod(" run" , primarySources::class .java, args::class .java)
70- .invoke(null , primarySources, args)
65+ val springFacadeInstance = classLoader
66+ .loadClass(" org.utbot.spring.instantiator.SpringApplicationInstantiatorFacade" )
67+ .getConstructor()
68+ .newInstance()
69+ springFacadeInstance as ApplicationInstantiatorFacade
70+
71+ // TODO: recreate context/app every time whenever we change method under test
72+ springContext = springFacadeInstance.instantiate(instantiationSettings)
73+ ? : error(" Failed to initialize Spring context" )
7174 }
7275
7376 override fun invoke (
@@ -79,20 +82,11 @@ class SpringUtExecutionInstrumentation(
7982 RepositoryInteraction .recordedInteractions.clear()
8083 // TODO properly detect which beans need to be reset, right now "orderRepository" and "orderService" are hardcoded
8184 val beanNamesToReset = listOf (" orderRepository" , " orderService" )
85+
8286 beanNamesToReset.forEach { beanNameToReset ->
83- val beanDefToReset = springContext::class .java
84- .getMethod(" getBeanDefinition" , String ::class .java)
85- .invoke(springContext, beanNameToReset)
86- springContext::class .java
87- .getMethod(" removeBeanDefinition" , String ::class .java)
88- .invoke(springContext, beanNameToReset)
89- springContext::class .java
90- .getMethod(
91- " registerBeanDefinition" ,
92- String ::class .java,
93- utContext.classLoader.loadClass(" org.springframework.beans.factory.config.BeanDefinition" )
94- )
95- .invoke(springContext, beanNameToReset, beanDefToReset)
87+ val beanDefToReset = springContext.getBeanDefinition(beanNameToReset)
88+ springContext.removeBeanDefinition(beanNameToReset)
89+ springContext.registerBeanDefinition(beanNameToReset, beanDefToReset)
9690 }
9791
9892 val jdbcTemplate = getBean(" jdbcTemplate" )
@@ -124,10 +118,7 @@ class SpringUtExecutionInstrumentation(
124118 }
125119 }
126120
127- fun getBean (beanName : String ): Any =
128- springContext::class .java
129- .getMethod(" getBean" , String ::class .java)
130- .invoke(springContext, beanName)
121+ fun getBean (beanName : String ): Any = springContext.getBean(beanName)
131122
132123 fun saveToRepository (repository : Any , entity : Any ) {
133124 // ignore repository interactions done during repository fill up
0 commit comments