[maven][eel][jps][IDEA-375248][IJ-CR-174659] fix stale JPS compilation cache on a remote target

The error was caused by reusing the old cache for compilation. As a result, the file with the compiler settings did not match the current state of the project. This led to the module being compiled with the version of the target Java bytecode that was used for the first compilation.

(cherry picked from commit 3a5e40192f664ca842750b2d276b7b4b44d67eaa)

GitOrigin-RevId: 0c92032a08d879395dab676f330162b3c0d81c2f
This commit is contained in:
Alexander.Glukhov
2025-09-03 18:26:03 +02:00
committed by intellij-monorepo-bot
parent 139f30fe69
commit 7effbac67f
3 changed files with 40 additions and 6 deletions

View File

@@ -75,4 +75,15 @@ interface BuildCommandLineBuilder {
default @NotNull Path copyProjectSpecificPathToTargetIfRequired(@NotNull Project project, @NotNull Path path) throws FileSystemException {
return path;
}
/**
* Synchronize the content of the path with the remote. This method replaces all the files located on the remote path with the content
* from the local machine.
* @param path a path to a project-specific which is available locally to the IDE that can be used only with specific {@link project}.
* @return a path which points to a copy on a remote machine.
*/
@ApiStatus.Experimental
default @NotNull Path syncProjectSpecificPathWithTarget(@NotNull Project project, @NotNull Path path) throws FileSystemException {
return path;
}
}

View File

@@ -1501,7 +1501,7 @@ public final class BuildManager implements Disposable {
try {
cmdLine.addPathParameter(
"-D" + GlobalOptions.EXTERNAL_PROJECT_CONFIG + '=',
cmdLine.copyProjectSpecificPathToTargetIfRequired(project, externalProjectConfig)
cmdLine.syncProjectSpecificPathWithTarget(project, externalProjectConfig)
);
}
catch (NoSuchFileException ignored) {

View File

@@ -14,11 +14,15 @@ import com.intellij.platform.eel.*
import com.intellij.platform.eel.provider.*
import com.intellij.platform.eel.provider.utils.EelPathUtils
import com.intellij.platform.eel.provider.utils.forwardLocalServer
import com.intellij.util.io.createDirectories
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.future.asCompletableFuture
import java.nio.charset.Charset
import java.nio.file.FileSystems
import java.nio.file.Path
import kotlin.io.path.ExperimentalPathApi
import kotlin.io.path.deleteRecursively
import kotlin.io.path.exists
import kotlin.io.path.name
class EelBuildCommandLineBuilder(val project: Project, exePath: Path) : BuildCommandLineBuilder {
@@ -31,6 +35,12 @@ class EelBuildCommandLineBuilder(val project: Project, exePath: Path) : BuildCom
private val workingDirectory: Path = getSystemSubfolder(BuildManager.SYSTEM_ROOT)
private val cacheDirectory: Path = getSystemSubfolder("jps-${ApplicationInfo.getInstance().getBuild()}")
.resolve(project.getProjectCacheFileName())
init {
workingDirectory.createDirectories() // Ijent doesn't support running anything in non-existing directory
cacheDirectory.createDirectories()
}
override fun addParameter(parameter: String) {
commandLine.addParameter(parameter)
@@ -73,13 +83,26 @@ class EelBuildCommandLineBuilder(val project: Project, exePath: Path) : BuildCom
return EelPathUtils.transferLocalContentToRemote(path, EelPathUtils.TransferTarget.Explicit(remotePath))
}
override fun copyProjectSpecificPathToTargetIfRequired(project: Project, path: Path): Path {
if (path.getEelDescriptor() != LocalEelDescriptor) {
override fun copyProjectSpecificPathToTargetIfRequired(project: Project, path: Path): Path = EelPathUtils.transferLocalContentToRemote(
path,
EelPathUtils.TransferTarget.Explicit(cacheDirectory.resolve(path.name))
)
@OptIn(ExperimentalPathApi::class)
override fun syncProjectSpecificPathWithTarget(project: Project, path: Path): Path {
val target = cacheDirectory.resolve(path.name)
if (target.getEelDescriptor() == LocalEelDescriptor) {
return path
}
val cacheFileName = project.getProjectCacheFileName()
val target = cacheDirectory.resolve(cacheFileName).resolve(path.name)
return EelPathUtils.transferLocalContentToRemote(path, EelPathUtils.TransferTarget.Explicit(target))
// this code should be replaced with com.intellij.platform.eel.provider.utils.EelPathUtils.incrementalWalkingTransfer when
// it's ready for production
if (target.exists()) {
target.deleteRecursively()
}
return EelPathUtils.transferLocalContentToRemote(
path,
EelPathUtils.TransferTarget.Explicit(target)
)
}
override fun getYjpAgentPath(yourKitProfilerService: YourKitProfilerService?): String? {