-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Start Spring analyzer process from engine process to use RD logger
- Loading branch information
1 parent
52efe90
commit 102c652
Showing
25 changed files
with
472 additions
and
345 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
utbot-core/src/main/kotlin/org/utbot/common/StandardStreamUtil.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package org.utbot.common | ||
|
||
import java.io.OutputStream | ||
import java.io.PrintStream | ||
|
||
fun silentlyCloseStandardStreams() { | ||
// we should change out/err streams as not to spend time on user output | ||
// and also because rd default logging system writes some initial values to stdout, polluting it as well | ||
val tmpStream = PrintStream(object : OutputStream() { | ||
override fun write(b: Int) {} | ||
}) | ||
val prevOut = System.out | ||
val prevError = System.err | ||
System.setOut(tmpStream) | ||
System.setErr(tmpStream) | ||
// stdin/stderr should be closed as not to leave hanging descriptors | ||
// and we cannot log any exceptions here as rd remote logging is still not configured | ||
// so we pass any exceptions | ||
silent { prevOut.close() } | ||
silent { prevError.close() } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
utbot-framework-api/src/main/kotlin/org/utbot/framework/process/CommonProcessArgs.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package org.utbot.framework.process | ||
|
||
import org.utbot.common.osSpecificJavaExecutable | ||
import org.utbot.framework.plugin.services.JdkInfoService | ||
import org.utbot.rd.rdPortArgument | ||
import java.io.File | ||
import java.nio.file.Path | ||
import kotlin.io.path.pathString | ||
|
||
private val javaExecutablePathString: Path | ||
get() = JdkInfoService.jdkInfoProvider.info.path.resolve("bin${File.separatorChar}${osSpecificJavaExecutable()}") | ||
|
||
// TODO use it in EngineProcess and InstrumentedProcess | ||
fun withCommonProcessCommandLineArgs( | ||
processSpecificArgs: List<String>, | ||
debugPort: Int, | ||
runWithDebug: Boolean, | ||
suspendExecutionInDebugMode: Boolean, | ||
rdPort: Int | ||
): List<String> = buildList { | ||
val suspendValue = if (suspendExecutionInDebugMode) "y" else "n" | ||
val debugArgument = "-agentlib:jdwp=transport=dt_socket,server=n,suspend=${suspendValue},quiet=y,address=$debugPort" | ||
.takeIf { runWithDebug } | ||
|
||
add(javaExecutablePathString.pathString) | ||
val javaVersionSpecificArgs = OpenModulesContainer.javaVersionSpecificArguments | ||
if (javaVersionSpecificArgs.isNotEmpty()) { | ||
addAll(javaVersionSpecificArgs) | ||
} | ||
debugArgument?.let { add(it) } | ||
addAll(processSpecificArgs) | ||
add(rdPortArgument(rdPort)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 105 additions & 0 deletions
105
utbot-framework/src/main/kotlin/org/utbot/framework/process/SpringAnalyzerProcess.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package org.utbot.framework.process | ||
|
||
import com.jetbrains.rd.util.lifetime.LifetimeDefinition | ||
import kotlinx.coroutines.runBlocking | ||
import mu.KotlinLogging | ||
import org.apache.commons.io.FileUtils | ||
import org.utbot.common.getPid | ||
import org.utbot.common.utBotTempDirectory | ||
import org.utbot.framework.UtSettings | ||
import org.utbot.rd.ProcessWithRdServer | ||
import org.utbot.rd.exceptions.InstantProcessDeathException | ||
import org.utbot.rd.generated.LoggerModel | ||
import org.utbot.rd.generated.loggerModel | ||
import org.utbot.rd.generated.synchronizationModel | ||
import org.utbot.rd.loggers.UtRdKLogger | ||
import org.utbot.rd.loggers.setupRdLogger | ||
import org.utbot.rd.onSchedulerBlocking | ||
import org.utbot.rd.startBlocking | ||
import org.utbot.rd.startUtProcessWithRdServer | ||
import org.utbot.rd.terminateOnException | ||
import org.utbot.spring.process.generated.SpringAnalyzerParams | ||
import org.utbot.spring.process.generated.SpringAnalyzerProcessModel | ||
import org.utbot.spring.process.generated.springAnalyzerProcessModel | ||
import java.nio.file.Files | ||
|
||
class SpringAnalyzerProcessInstantDeathException : | ||
InstantProcessDeathException(UtSettings.springAnalyzerProcessDebugPort, UtSettings.runSpringAnalyzerProcessWithDebug) | ||
|
||
private const val SPRING_ANALYZER_JAR_FILENAME = "utbot-spring-analyzer-shadow.jar" | ||
private val logger = KotlinLogging.logger {} | ||
private val rdLogger = UtRdKLogger(logger, "") | ||
|
||
class SpringAnalyzerProcess private constructor( | ||
rdProcess: ProcessWithRdServer | ||
) : ProcessWithRdServer by rdProcess { | ||
|
||
companion object { | ||
private fun obtainProcessSpecificCommandLineArgs(): List<String> { | ||
val jarFile = | ||
Files.createDirectories(utBotTempDirectory.toFile().resolve("spring-analyzer").toPath()) | ||
.toFile().resolve(SPRING_ANALYZER_JAR_FILENAME) | ||
FileUtils.copyURLToFile( | ||
this::class.java.classLoader.getResource("lib/$SPRING_ANALYZER_JAR_FILENAME"), | ||
jarFile | ||
) | ||
return listOf( | ||
"-Dorg.apache.commons.logging.LogFactory=org.utbot.rd.loggers.RDApacheCommonsLogFactory", | ||
"-jar", | ||
jarFile.path | ||
) | ||
} | ||
|
||
fun createBlocking() = runBlocking { SpringAnalyzerProcess() } | ||
|
||
suspend operator fun invoke(): SpringAnalyzerProcess = LifetimeDefinition().terminateOnException { lifetime -> | ||
val rdProcess = startUtProcessWithRdServer(lifetime) { port -> | ||
val cmd = withCommonProcessCommandLineArgs( | ||
obtainProcessSpecificCommandLineArgs(), | ||
debugPort = UtSettings.springAnalyzerProcessDebugPort, | ||
runWithDebug = UtSettings.runSpringAnalyzerProcessWithDebug, | ||
suspendExecutionInDebugMode = UtSettings.suspendSpringAnalyzerProcessExecutionInDebugMode, | ||
rdPort = port | ||
) | ||
val process = ProcessBuilder(cmd) | ||
.directory(Files.createTempDirectory(utBotTempDirectory, "spring-analyzer").toFile()) | ||
.start() | ||
|
||
logger.info { "Spring Analyzer process started with PID = ${process.getPid}" } | ||
|
||
if (!process.isAlive) throw SpringAnalyzerProcessInstantDeathException() | ||
|
||
process | ||
} | ||
rdProcess.awaitProcessReady() | ||
val proc = SpringAnalyzerProcess(rdProcess) | ||
setupRdLogger(rdProcess, proc.loggerModel, rdLogger) | ||
return proc | ||
} | ||
} | ||
|
||
private val springAnalyzerModel: SpringAnalyzerProcessModel = onSchedulerBlocking { protocol.springAnalyzerProcessModel } | ||
private val loggerModel: LoggerModel = onSchedulerBlocking { protocol.loggerModel } | ||
|
||
init { | ||
lifetime.onTermination { | ||
protocol.synchronizationModel.stopProcess.fire(Unit) | ||
} | ||
} | ||
|
||
fun getBeanQualifiedNames( | ||
classpath: List<String>, | ||
configuration: String, | ||
propertyFilesPaths: List<String>, | ||
xmlConfigurationPaths: List<String> | ||
): List<String> { | ||
val params = SpringAnalyzerParams( | ||
classpath.toTypedArray(), | ||
configuration, | ||
propertyFilesPaths.toTypedArray(), | ||
xmlConfigurationPaths.toTypedArray() | ||
) | ||
val result = springAnalyzerModel.analyze.startBlocking(params) | ||
return result.beanTypes.toList() | ||
} | ||
} |
Oops, something went wrong.