Skip to content

Commit 723e27d

Browse files
committed
Resolve issues with SpringAnalyzerProcess
1 parent 8ffdeb4 commit 723e27d

File tree

15 files changed

+74
-69
lines changed

15 files changed

+74
-69
lines changed

utbot-framework-api/src/main/kotlin/org/utbot/framework/process/CommonProcessArgs.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import java.nio.file.Path
77
import kotlin.io.path.pathString
88

99
private val javaExecutablePathString: Path
10-
get() = JdkInfoService.jdkInfoProvider.info.path.resolve("bin${File.separatorChar}${osSpecificJavaExecutable()}")
10+
get() = JdkInfoService.provide().path.resolve("bin${File.separatorChar}${osSpecificJavaExecutable()}")
1111

1212
fun obtainCommonProcessCommandLineArgs(
1313
debugPort: Int,

utbot-framework/src/main/kotlin/org/utbot/framework/process/SpringAnalyzerProcess.kt

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ import org.utbot.rd.ProcessWithRdServer
1111
import org.utbot.rd.exceptions.InstantProcessDeathException
1212
import org.utbot.rd.generated.LoggerModel
1313
import org.utbot.rd.generated.loggerModel
14-
import org.utbot.rd.generated.synchronizationModel
1514
import org.utbot.rd.loggers.UtRdKLogger
16-
import org.utbot.rd.loggers.setupRdLogger
15+
import org.utbot.rd.loggers.setup
1716
import org.utbot.rd.onSchedulerBlocking
1817
import org.utbot.rd.rdPortArgument
1918
import org.utbot.rd.startBlocking
@@ -28,6 +27,8 @@ class SpringAnalyzerProcessInstantDeathException :
2827
InstantProcessDeathException(UtSettings.springAnalyzerProcessDebugPort, UtSettings.runSpringAnalyzerProcessWithDebug)
2928

3029
private const val SPRING_ANALYZER_JAR_FILENAME = "utbot-spring-analyzer-shadow.jar"
30+
private const val SPRING_ANALYZER_JAR_PATH = "lib/$SPRING_ANALYZER_JAR_FILENAME"
31+
private const val UNKNOWN_MODIFICATION_TIME = 0L
3132
private val logger = KotlinLogging.logger {}
3233
private val rdLogger = UtRdKLogger(logger, "")
3334

@@ -36,16 +37,34 @@ class SpringAnalyzerProcess private constructor(
3637
) : ProcessWithRdServer by rdProcess {
3738

3839
companion object {
39-
private fun obtainProcessSpecificCommandLineArgs(port: Int): List<String> {
40-
val jarFile =
41-
Files.createDirectories(utBotTempDirectory.toFile().resolve("spring-analyzer").toPath())
42-
.toFile().resolve(SPRING_ANALYZER_JAR_FILENAME)
43-
FileUtils.copyURLToFile(
44-
this::class.java.classLoader.getResource("lib/$SPRING_ANALYZER_JAR_FILENAME"),
45-
jarFile
46-
)
47-
return listOf(
48-
"-Dorg.apache.commons.logging.LogFactory=org.utbot.rd.loggers.RDApacheCommonsLogFactory",
40+
private val jarFile by lazy {
41+
Files.createDirectories(utBotTempDirectory.toFile().resolve("spring-analyzer").toPath())
42+
.toFile().resolve(SPRING_ANALYZER_JAR_FILENAME).also { jarFile ->
43+
val resource = this::class.java.classLoader.getResource(SPRING_ANALYZER_JAR_PATH)
44+
?: error("Unable to find \"$SPRING_ANALYZER_JAR_PATH\" in resources, make sure it's on the classpath")
45+
val resourceConnection = resource.openConnection()
46+
val lastResourceModification = try {
47+
resourceConnection.lastModified
48+
} finally {
49+
resourceConnection.getInputStream().close()
50+
}
51+
if (
52+
!jarFile.exists() ||
53+
jarFile.lastModified() == UNKNOWN_MODIFICATION_TIME ||
54+
lastResourceModification == UNKNOWN_MODIFICATION_TIME ||
55+
jarFile.lastModified() < lastResourceModification
56+
)
57+
FileUtils.copyURLToFile(resource, jarFile)
58+
}
59+
}
60+
61+
private fun obtainSpringAnalyzerProcessCommandLine(port: Int): List<String> {
62+
return obtainCommonProcessCommandLineArgs(
63+
debugPort = UtSettings.springAnalyzerProcessDebugPort,
64+
runWithDebug = UtSettings.runSpringAnalyzerProcessWithDebug,
65+
suspendExecutionInDebugMode = UtSettings.suspendSpringAnalyzerProcessExecutionInDebugMode,
66+
) + listOf(
67+
"-Dorg.apache.commons.logging.LogFactory=org.utbot.spring.loggers.RDApacheCommonsLogFactory",
4968
"-jar",
5069
jarFile.path,
5170
rdPortArgument(port)
@@ -56,11 +75,7 @@ class SpringAnalyzerProcess private constructor(
5675

5776
suspend operator fun invoke(): SpringAnalyzerProcess = LifetimeDefinition().terminateOnException { lifetime ->
5877
val rdProcess = startUtProcessWithRdServer(lifetime) { port ->
59-
val cmd = obtainCommonProcessCommandLineArgs(
60-
debugPort = UtSettings.springAnalyzerProcessDebugPort,
61-
runWithDebug = UtSettings.runSpringAnalyzerProcessWithDebug,
62-
suspendExecutionInDebugMode = UtSettings.suspendSpringAnalyzerProcessExecutionInDebugMode,
63-
) + obtainProcessSpecificCommandLineArgs(port)
78+
val cmd = obtainSpringAnalyzerProcessCommandLine(port)
6479
val process = ProcessBuilder(cmd)
6580
.directory(Files.createTempDirectory(utBotTempDirectory, "spring-analyzer").toFile())
6681
.start()
@@ -73,20 +88,14 @@ class SpringAnalyzerProcess private constructor(
7388
}
7489
rdProcess.awaitProcessReady()
7590
val proc = SpringAnalyzerProcess(rdProcess)
76-
setupRdLogger(rdProcess, proc.loggerModel, rdLogger)
91+
proc.loggerModel.setup(rdLogger, proc.lifetime)
7792
return proc
7893
}
7994
}
8095

8196
private val springAnalyzerModel: SpringAnalyzerProcessModel = onSchedulerBlocking { protocol.springAnalyzerProcessModel }
8297
private val loggerModel: LoggerModel = onSchedulerBlocking { protocol.loggerModel }
8398

84-
init {
85-
lifetime.onTermination {
86-
protocol.synchronizationModel.stopProcess.fire(Unit)
87-
}
88-
}
89-
9099
fun getBeanQualifiedNames(
91100
classpath: List<String>,
92101
configuration: String,

utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/process/InstrumentedProcessMain.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ import org.utbot.rd.RdSettingsContainerFactory
2121
import org.utbot.rd.findRdPort
2222
import org.utbot.rd.generated.loggerModel
2323
import org.utbot.rd.generated.settingsModel
24-
import org.utbot.rd.generated.synchronizationModel
2524
import org.utbot.rd.loggers.UtRdRemoteLoggerFactory
25+
import org.utbot.rd.silentlyCloseStandardStreams
2626
import java.io.File
2727
import java.net.URLClassLoader
2828
import java.security.AllPermission
@@ -97,7 +97,7 @@ fun main(args: Array<String>) = runBlocking {
9797

9898
try {
9999
ClientProtocolBuilder().withProtocolTimeout(messageFromMainTimeout).start(port) {
100-
synchronizationModel.initRemoteLogging.adviseOnce(lifetime) {
100+
loggerModel.initRemoteLogging.adviseOnce(lifetime) {
101101
Logger.set(Lifetime.Eternal, UtRdRemoteLoggerFactory(loggerModel))
102102
this.protocol.scheduler.queue { warmupMockito() }
103103
}

utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/rd/InstrumentedProcess.kt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,8 @@ import org.utbot.rd.ProcessWithRdServer
1414
import org.utbot.rd.exceptions.InstantProcessDeathException
1515
import org.utbot.rd.generated.LoggerModel
1616
import org.utbot.rd.generated.loggerModel
17-
import org.utbot.rd.generated.synchronizationModel
1817
import org.utbot.rd.loggers.UtRdKLogger
19-
import org.utbot.rd.loggers.UtRdRemoteLogger
20-
import org.utbot.rd.loggers.setupRdLogger
18+
import org.utbot.rd.loggers.setup
2119
import org.utbot.rd.onSchedulerBlocking
2220
import org.utbot.rd.startUtProcessWithRdServer
2321
import org.utbot.rd.terminateOnException
@@ -64,7 +62,7 @@ class InstrumentedProcess private constructor(
6462
logger.trace("rd process started")
6563

6664
val proc = InstrumentedProcess(classLoader, rdProcess)
67-
setupRdLogger(rdProcess, proc.loggerModel, rdLogger)
65+
proc.loggerModel.setup(rdLogger, proc.lifetime)
6866

6967
proc.lifetime.onTermination {
7068
logger.trace { "process is terminating" }

utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/process/EngineProcess.kt

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -102,25 +102,26 @@ class EngineProcess private constructor(val project: Project, private val classN
102102

103103
private const val startFileName = "org.utbot.framework.process.EngineProcessMainKt"
104104

105-
private fun obtainProcessSpecificCommandLineArgs(port: Int) = listOf(
106-
"-ea",
107-
log4j2ConfigSwitch,
108-
"-cp",
109-
pluginClasspath,
110-
startFileName,
111-
rdPortArgument(port)
112-
)
105+
private fun obtainEngineProcessCommandLine(port: Int): List<String> =
106+
obtainCommonProcessCommandLineArgs(
107+
debugPort = UtSettings.engineProcessDebugPort,
108+
runWithDebug = UtSettings.runEngineProcessWithDebug,
109+
suspendExecutionInDebugMode = UtSettings.suspendEngineProcessExecutionInDebugMode,
110+
) + listOf(
111+
"-ea",
112+
log4j2ConfigSwitch,
113+
"-cp",
114+
pluginClasspath,
115+
startFileName,
116+
rdPortArgument(port)
117+
)
113118

114119
fun createBlocking(project: Project, classNameToPath: Map<String, String?>): EngineProcess = runBlocking { EngineProcess(project, classNameToPath) }
115120

116121
suspend operator fun invoke(project: Project, classNameToPath: Map<String, String?>): EngineProcess =
117122
LifetimeDefinition().terminateOnException { lifetime ->
118123
val rdProcess = startUtProcessWithRdServer(lifetime) { port ->
119-
val cmd = obtainCommonProcessCommandLineArgs(
120-
debugPort = UtSettings.engineProcessDebugPort,
121-
runWithDebug = UtSettings.runEngineProcessWithDebug,
122-
suspendExecutionInDebugMode = UtSettings.suspendEngineProcessExecutionInDebugMode,
123-
) + obtainProcessSpecificCommandLineArgs(port)
124+
val cmd = obtainEngineProcessCommandLine(port)
124125
val directory = WorkingDirService.provide().toFile()
125126
val builder = ProcessBuilder(cmd).directory(directory)
126127
val process = builder.start()

utbot-rd/build.gradle

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ dependencies {
6969
implementation group: 'com.jetbrains.rd', name: 'rd-core', version: rdVersion
7070

7171
implementation group: 'io.github.microutils', name: 'kotlin-logging', version: kotlinLoggingVersion
72-
implementation group: 'commons-logging', name: 'commons-logging', version: commonsLoggingVersion
7372

7473
processWithRdServerMockImplementation project(':utbot-rd')
7574

utbot-core/src/main/kotlin/org/utbot/common/StandardStreamUtil.kt renamed to utbot-rd/src/main/kotlin/org/utbot/rd/StandardStreamUtil.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
package org.utbot.common
1+
package org.utbot.rd
22

3+
import org.utbot.common.silent
34
import java.io.OutputStream
45
import java.io.PrintStream
56

utbot-rd/src/main/kotlin/org/utbot/rd/generated/LoggerModel.Generated.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import kotlin.jvm.JvmStatic
1818
* #### Generated from [LoggerModel.kt:8]
1919
*/
2020
class LoggerModel private constructor(
21+
private val _initRemoteLogging: RdSignal<Unit>,
2122
private val _log: RdSignal<LogArguments>,
2223
private val _getCategoryMinimalLogLevel: RdCall<String, Int>
2324
) : RdExtBase() {
@@ -47,13 +48,14 @@ class LoggerModel private constructor(
4748
}
4849

4950

50-
const val serializationHash = -6259198217478203203L
51+
const val serializationHash = 1686273842005935878L
5152

5253
}
5354
override val serializersOwner: ISerializersOwner get() = LoggerModel
5455
override val serializationHash: Long get() = LoggerModel.serializationHash
5556

5657
//fields
58+
val initRemoteLogging: IAsyncSignal<Unit> get() = _initRemoteLogging
5759
val log: IAsyncSignal<LogArguments> get() = _log
5860

5961
/**
@@ -64,18 +66,21 @@ class LoggerModel private constructor(
6466
//methods
6567
//initializer
6668
init {
69+
_initRemoteLogging.async = true
6770
_log.async = true
6871
_getCategoryMinimalLogLevel.async = true
6972
}
7073

7174
init {
75+
bindableChildren.add("initRemoteLogging" to _initRemoteLogging)
7276
bindableChildren.add("log" to _log)
7377
bindableChildren.add("getCategoryMinimalLogLevel" to _getCategoryMinimalLogLevel)
7478
}
7579

7680
//secondary constructor
7781
private constructor(
7882
) : this(
83+
RdSignal<Unit>(FrameworkMarshallers.Void),
7984
RdSignal<LogArguments>(LogArguments),
8085
RdCall<String, Int>(FrameworkMarshallers.String, FrameworkMarshallers.Int)
8186
)
@@ -86,6 +91,7 @@ class LoggerModel private constructor(
8691
override fun print(printer: PrettyPrinter) {
8792
printer.println("LoggerModel (")
8893
printer.indent {
94+
print("initRemoteLogging = "); _initRemoteLogging.print(printer); println()
8995
print("log = "); _log.print(printer); println()
9096
print("getCategoryMinimalLogLevel = "); _getCategoryMinimalLogLevel.print(printer); println()
9197
}
@@ -94,6 +100,7 @@ class LoggerModel private constructor(
94100
//deepClone
95101
override fun deepClone(): LoggerModel {
96102
return LoggerModel(
103+
_initRemoteLogging.deepClonePolymorphic(),
97104
_log.deepClonePolymorphic(),
98105
_getCategoryMinimalLogLevel.deepClonePolymorphic()
99106
)

utbot-rd/src/main/kotlin/org/utbot/rd/generated/SynchronizationModel.Generated.kt

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import kotlin.jvm.JvmStatic
1919
*/
2020
class SynchronizationModel private constructor(
2121
private val _suspendTimeoutTimer: RdCall<Boolean, Unit>,
22-
private val _initRemoteLogging: RdSignal<Unit>,
2322
private val _synchronizationSignal: RdSignal<String>,
2423
private val _stopProcess: RdSignal<Unit>
2524
) : RdExtBase() {
@@ -48,15 +47,14 @@ class SynchronizationModel private constructor(
4847
}
4948

5049

51-
const val serializationHash = 5881306106692642003L
50+
const val serializationHash = -8851121542976813112L
5251

5352
}
5453
override val serializersOwner: ISerializersOwner get() = SynchronizationModel
5554
override val serializationHash: Long get() = SynchronizationModel.serializationHash
5655

5756
//fields
5857
val suspendTimeoutTimer: RdCall<Boolean, Unit> get() = _suspendTimeoutTimer
59-
val initRemoteLogging: IAsyncSignal<Unit> get() = _initRemoteLogging
6058
val synchronizationSignal: IAsyncSignal<String> get() = _synchronizationSignal
6159

6260
/**
@@ -67,14 +65,12 @@ class SynchronizationModel private constructor(
6765
//initializer
6866
init {
6967
_suspendTimeoutTimer.async = true
70-
_initRemoteLogging.async = true
7168
_synchronizationSignal.async = true
7269
_stopProcess.async = true
7370
}
7471

7572
init {
7673
bindableChildren.add("suspendTimeoutTimer" to _suspendTimeoutTimer)
77-
bindableChildren.add("initRemoteLogging" to _initRemoteLogging)
7874
bindableChildren.add("synchronizationSignal" to _synchronizationSignal)
7975
bindableChildren.add("stopProcess" to _stopProcess)
8076
}
@@ -83,7 +79,6 @@ class SynchronizationModel private constructor(
8379
private constructor(
8480
) : this(
8581
RdCall<Boolean, Unit>(FrameworkMarshallers.Bool, FrameworkMarshallers.Void),
86-
RdSignal<Unit>(FrameworkMarshallers.Void),
8782
RdSignal<String>(FrameworkMarshallers.String),
8883
RdSignal<Unit>(FrameworkMarshallers.Void)
8984
)
@@ -95,7 +90,6 @@ class SynchronizationModel private constructor(
9590
printer.println("SynchronizationModel (")
9691
printer.indent {
9792
print("suspendTimeoutTimer = "); _suspendTimeoutTimer.print(printer); println()
98-
print("initRemoteLogging = "); _initRemoteLogging.print(printer); println()
9993
print("synchronizationSignal = "); _synchronizationSignal.print(printer); println()
10094
print("stopProcess = "); _stopProcess.print(printer); println()
10195
}
@@ -105,7 +99,6 @@ class SynchronizationModel private constructor(
10599
override fun deepClone(): SynchronizationModel {
106100
return SynchronizationModel(
107101
_suspendTimeoutTimer.deepClonePolymorphic(),
108-
_initRemoteLogging.deepClonePolymorphic(),
109102
_synchronizationSignal.deepClonePolymorphic(),
110103
_stopProcess.deepClonePolymorphic()
111104
)

utbot-rd/src/main/kotlin/org/utbot/rd/loggers/UtRdLogUtil.kt

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ import com.jetbrains.rd.util.*
44
import com.jetbrains.rd.util.lifetime.Lifetime
55
import mu.KLogger
66
import org.utbot.common.LoggerWithLogMethod
7-
import org.utbot.rd.ProcessWithRdServer
87
import org.utbot.rd.generated.LoggerModel
9-
import org.utbot.rd.generated.synchronizationModel
10-
118

129
fun Logger.withLevel(logLevel: LogLevel): LoggerWithLogMethod = LoggerWithLogMethod {
1310
this.log(logLevel, it)
@@ -29,19 +26,19 @@ fun overrideDefaultRdLoggerFactoryWithKLogger(logger: KLogger) {
2926
}
3027
}
3128

32-
fun setupRdLogger(rdProcess: ProcessWithRdServer, loggerModel: LoggerModel, rdLogger: UtRdKLogger) {
29+
fun LoggerModel.setup(rdLogger: UtRdKLogger, processLifetime: Lifetime) {
3330
// currently we do not specify log level for different categories
3431
// though it is possible with some additional map on categories -> consider performance
35-
loggerModel.getCategoryMinimalLogLevel.set { _ ->
32+
getCategoryMinimalLogLevel.set { _ ->
3633
// this logLevel is obtained from KotlinLogger
3734
rdLogger.logLevel.ordinal
3835
}
3936

40-
loggerModel.log.advise(rdProcess.lifetime) {
37+
log.advise(processLifetime) {
4138
val logLevel = UtRdRemoteLogger.logLevelValues[it.logLevelOrdinal]
4239
// assume throwable already in message
4340
rdLogger.log(logLevel, it.message, null)
4441
}
4542

46-
rdProcess.protocol.synchronizationModel.initRemoteLogging.fire(Unit)
43+
initRemoteLogging.fire(Unit)
4744
}

utbot-rd/src/main/rdgen/org/utbot/rd/models/LoggerModel.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ object LoggerModel : Ext(LoggerRoot) {
1313
}
1414

1515
init {
16+
signal("initRemoteLogging", PredefinedType.void).async
1617
signal("log", logArguments).async
1718
call(
1819
"getCategoryMinimalLogLevel",

utbot-rd/src/main/rdgen/org/utbot/rd/models/SynchronizationModel.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ object SynchronizationRoot: Root()
88
object SynchronizationModel: Ext(SynchronizationRoot) {
99
init {
1010
call("suspendTimeoutTimer", PredefinedType.bool, PredefinedType.void).async
11-
signal("initRemoteLogging", PredefinedType.void).async
1211
signal("synchronizationSignal", PredefinedType.string).async
1312
signal("StopProcess", PredefinedType.void).apply {
1413
async

utbot-spring-analyzer/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ import com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCach
22
import com.github.jengelman.gradle.plugins.shadow.transformers.PropertiesFileTransformer
33

44
val rdVersion: String by rootProject
5-
val log4j2Version: String by rootProject
6-
val kotlinLoggingVersion: String? by rootProject
5+
val commonsLoggingVersion: String by rootProject
76

87
plugins {
98
id("org.springframework.boot") version "2.7.8"
@@ -27,6 +26,7 @@ dependencies {
2726
implementation(project(":utbot-core"))
2827
implementation("com.jetbrains.rd:rd-framework:$rdVersion")
2928
implementation("com.jetbrains.rd:rd-core:$rdVersion")
29+
implementation("commons-logging:commons-logging:$commonsLoggingVersion")
3030
}
3131

3232
application {

0 commit comments

Comments
 (0)