diff --git a/platform/execution-impl/testSources/com/intellij/terminal/TestJavaMainClassCommand.kt b/platform/execution-impl/testSources/com/intellij/terminal/TestJavaMainClassCommand.kt index b933b8dfd7c6..c95f76949a6e 100644 --- a/platform/execution-impl/testSources/com/intellij/terminal/TestJavaMainClassCommand.kt +++ b/platform/execution-impl/testSources/com/intellij/terminal/TestJavaMainClassCommand.kt @@ -2,29 +2,40 @@ package com.intellij.terminal import com.intellij.openapi.application.PathManager -import com.intellij.platform.eel.EelExecApiHelpers -import com.intellij.platform.eel.pathSeparator +import com.intellij.openapi.diagnostic.logger +import com.intellij.platform.eel.* import com.intellij.platform.eel.provider.LocalEelDescriptor -import com.intellij.platform.eel.provider.localEel -import com.intellij.platform.eel.spawnProcess +import com.intellij.platform.eel.provider.toEelApi import com.intellij.util.execution.ParametersListUtil import java.nio.file.Path import kotlin.io.path.Path +import kotlin.io.path.div +import kotlin.io.path.pathString +import kotlin.jvm.optionals.getOrElse internal class TestJavaMainClassCommand( private val mainClass: Class<*>, dependencies: List>, private val args: List, ) { - private val javaExe: Path = Path(ProcessHandle.current().info().command().get()) - private val classPath: String = getClassPath(mainClass, dependencies) + private val javaExe: Path = Path(ProcessHandle.current().info().command().getOrElse { + // In rare cases on macOS, `ProcessHandle.current().info().command()` may be empty for unknown reasons. + val failover = Path(System.getProperty("java.home")) / "bin" / (if (eelDescriptor.osFamily.isWindows) "java.exe" else "java") + logger().warn("Cannot find java executable, using failover: $failover") + failover.pathString + }) + private val classpathEntries: List = getClasspathEntries(mainClass, dependencies) + + private val eelDescriptor: EelDescriptor + get() = LocalEelDescriptor val commandLine: String get() = ParametersListUtil.join(listOf(javaExe.toString(), mainClass.canonicalName) + args) - fun createLocalProcessBuilder(): EelExecApiHelpers.SpawnProcess { - return localEel.exec.spawnProcess(javaExe.toString()) - .env(mapOf("CLASSPATH" to classPath)) + suspend fun createLocalProcessBuilder(): EelExecApiHelpers.SpawnProcess { + val classpath = classpathEntries.joinToString(eelDescriptor.osFamily.pathSeparator) { it.pathString } + return eelDescriptor.toEelApi().exec.spawnProcess(javaExe.pathString) + .env(mapOf("CLASSPATH" to classpath)) .args(listOf(mainClass.canonicalName) + args) } @@ -33,11 +44,10 @@ internal class TestJavaMainClassCommand( } private companion object { - private fun getClassPath(mainClass: Class<*>, dependencies: List>): String { - val classPathRoots = (listOf(mainClass, KotlinVersion::class.java /* kotlin-stdlib.jar */) + dependencies).map { - checkNotNull(PathManager.getJarPathForClass(it)) { "Cannot find jar/directory for $it" } + private fun getClasspathEntries(mainClass: Class<*>, dependencies: List>): List { + return (listOf(mainClass, KotlinVersion::class.java /* kotlin-stdlib.jar */) + dependencies).map { + checkNotNull(PathManager.getJarForClass(it)) { "Cannot find jar/directory for $it" } }.distinct() - return classPathRoots.joinToString(LocalEelDescriptor.osFamily.pathSeparator) } } }