@@ -51,7 +51,6 @@ import org.utbot.instrumentation.instrumentation.execution.mock.InstanceMockCont
51
51
import org.utbot.instrumentation.instrumentation.execution.mock.MethodMockController
52
52
import org.utbot.instrumentation.instrumentation.execution.mock.MockController
53
53
import org.utbot.instrumentation.process.runSandbox
54
- import java.lang.reflect.Method
55
54
import java.lang.reflect.Modifier
56
55
import java.security.AccessController
57
56
import java.security.PrivilegedAction
@@ -130,6 +129,14 @@ class InstrumentationContextAwareValueConstructor(
130
129
}
131
130
}
132
131
132
+ /* *
133
+ * Use this method if you need to use [construct], while being in a sandbox.
134
+ *
135
+ * Permission elevation is required, because [construct] heavily uses reflection and Mockito.
136
+ */
137
+ private fun constructPrivileged (model : UtModel ): UtConcreteValue <* > =
138
+ AccessController .doPrivileged(PrivilegedAction { construct(model) })
139
+
133
140
/* *
134
141
* Constructs an Enum<*> instance by model, uses reference-equality cache.
135
142
*/
@@ -242,24 +249,26 @@ class InstrumentationContextAwareValueConstructor(
242
249
with (invocation.method) {
243
250
mockedExecutables.getOrPut(executableId) {
244
251
detectedMockingCandidates.add(executableId)
245
- val answerModel = generateNewAnswerModel()
252
+ var answerModel = generateNewAnswerModel(executableId)
253
+ val answerValue = runCatching { constructPrivileged(answerModel) }.getOrElse {
254
+ // fallback is used, so we still get some value (null) for types
255
+ // that can't be mocked, e.g. arrays and sealed interfaces
256
+ answerModel = executableId.returnType.defaultValueModel()
257
+ constructPrivileged(answerModel)
258
+ }
246
259
247
260
MockedExecutable (
248
261
executableId = executableId,
249
- answerValues = listOf (
250
- // `construct()` heavily uses reflection and Mockito,
251
- // so it can't run in sandbox and we need to elevate permissions
252
- AccessController .doPrivileged(PrivilegedAction { construct(answerModel) })
253
- .value.takeUnless { it == Unit }
254
- ),
262
+ // `Unit` is replaced with `null`, because in Java `void` methods actually return `null`
263
+ answerValues = listOf (answerValue.value.takeUnless { it == Unit }),
255
264
answerModels = listOf (answerModel)
256
265
)
257
266
}.nextAnswer()
258
267
}
259
268
}
260
269
}
261
270
262
- private fun Method. generateNewAnswerModel () =
271
+ private fun generateNewAnswerModel (executableId : ExecutableId ) =
263
272
executableId.returnType.defaultValueModel().takeUnless { it.isNull() } ? : when (executableId.returnType) {
264
273
// mockito can't mock `String` and `Class`
265
274
stringClassId -> UtNullModel (stringClassId)
0 commit comments