diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildCommandLineBuilder.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildCommandLineBuilder.java index be268b38a2b0..e810c63e1316 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildCommandLineBuilder.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildCommandLineBuilder.java @@ -48,14 +48,25 @@ interface BuildCommandLineBuilder { } /** - * @param path a path which is available locally to the IDE + * @param path a path to a project-agnostic file which is available locally to the IDE. * @return a path which points to a copy on a remote machine, and is available to the IDE (but maybe not to the OS of the IDE) * i.e., in case of WSL the original path could be {@code C:\Users\a.zip}, and the returned path would be {@code \\wsl.localhost\home\a.zip}. + * The file will be copied to a project-independent location; if the file already exists on the target machine, it will not be copied, + * and the path to the existing file will be returned. + * This method could be used to copy all the project-independent files like non-snapshot libraries, java agents and other tooling. */ default @NotNull Path copyProjectAgnosticPathToTargetIfRequired(@NotNull Path path) throws FileSystemException { return path; } + /** + * @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, and is available to the IDE (but maybe not to the OS of the IDE) + * i.e., in case of WSL the original path could be {@code C:\Users\a.zip}, and the returned path would be {@code \\wsl.localhost\home\a.zip}. + * The file will be copied to a project-dependent location; if the file already exists on the target machine, it will not be copied, + * and the path to the existing file will be returned. + * This method could be used to copy project-dependent files like metadata for a compiler. + */ @ApiStatus.Experimental default @NotNull Path copyProjectSpecificPathToTargetIfRequired(@NotNull Project project, @NotNull Path path) throws FileSystemException { return path; diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index ad5d0ca7d5b0..ceb005d120b3 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -1454,23 +1454,7 @@ public final class BuildManager implements Disposable { cmdLine.addParameter("-D" + JPS_USE_EXPERIMENTAL_STORAGE + "=true"); } - String jnaBootLibraryPath = System.getProperty("jna.boot.library.path"); - if (jnaBootLibraryPath != null && wslPath == null) { - //noinspection SpellCheckingInspection - try { - cmdLine.addPathParameter( - "-Djna.boot.library.path=", - cmdLine.copyProjectAgnosticPathToTargetIfRequired(Path.of(jnaBootLibraryPath)) - ); - } - catch (FileSystemException err) { - LOG.warn("Can't copy JNA", err); - } - //noinspection SpellCheckingInspection - cmdLine.addParameter("-Djna.nosys=true"); - //noinspection SpellCheckingInspection - cmdLine.addParameter("-Djna.noclasspath=true"); - } + attachJnaBootLibraryIfNeeded(project, cmdLine, wslPath); if (Registry.is("jps.build.use.workspace.model")) { // todo: upload workspace model to remote side because it runs with eel String globalCacheId = "Local"; @@ -1691,7 +1675,7 @@ public final class BuildManager implements Disposable { for (Pair parameter : provider.getPathParameters()) { try { - cmdLine.addPathParameter(parameter.getFirst(), cmdLine.copyProjectAgnosticPathToTargetIfRequired(parameter.getSecond())); + cmdLine.addPathParameter(parameter.getFirst(), cmdLine.copyProjectSpecificPathToTargetIfRequired(project, parameter.getSecond())); } catch (FileSystemException err) { throw new ExecutionException("Failed to copy parameter " + parameter.getFirst(), err); @@ -1760,7 +1744,7 @@ public final class BuildManager implements Disposable { for (BuildProcessParametersProvider buildProcessParametersProvider : BuildProcessParametersProvider.EP_NAME.getExtensions(project)) { for (String path : buildProcessParametersProvider.getAdditionalPluginPaths()) { try { - cmdLine.copyProjectAgnosticPathToTargetIfRequired(Paths.get(path)); + cmdLine.copyProjectSpecificPathToTargetIfRequired(project, Paths.get(path)); } catch (FileSystemException err) { throw new ExecutionException("Failed to copy additional plugin", err); @@ -1835,6 +1819,30 @@ public final class BuildManager implements Disposable { return processHandler; } + private static void attachJnaBootLibraryIfNeeded( + @NotNull Project project, + @NotNull BuildCommandLineBuilder cmdLine, + @Nullable WslPath wslPath + ) { + // it's impossible to use a Windows DLL inside a WSL environment + if (wslPath != null) { + return; + } + // it's impossible to use a Windows DLL inside a non-local environment + if (!(EelProviderUtil.getEelDescriptor(project) instanceof LocalEelDescriptor)) { + return; + } + String jnaBootLibraryPath = System.getProperty("jna.boot.library.path"); + if (jnaBootLibraryPath != null) { + //noinspection SpellCheckingInspection + cmdLine.addPathParameter("-Djna.boot.library.path=", jnaBootLibraryPath); + //noinspection SpellCheckingInspection + cmdLine.addParameter("-Djna.nosys=true"); + //noinspection SpellCheckingInspection + cmdLine.addParameter("-Djna.noclasspath=true"); + } + } + private static void showSnapshotNotificationAfterFinish(@NotNull Project project) { MessageBusConnection busConnection = project.getMessageBus().connect(); busConnection.subscribe(BuildManagerListener.TOPIC, new BuildManagerListener() { diff --git a/java/compiler/impl/src/com/intellij/compiler/server/EelBuildCommandLineBuilder.kt b/java/compiler/impl/src/com/intellij/compiler/server/EelBuildCommandLineBuilder.kt index 6b7d59a20df2..397dd18eceb9 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/EelBuildCommandLineBuilder.kt +++ b/java/compiler/impl/src/com/intellij/compiler/server/EelBuildCommandLineBuilder.kt @@ -48,7 +48,7 @@ class EelBuildCommandLineBuilder(val project: Project, exePath: Path) : BuildCom override fun addClasspathParameter(classpathInHost: List, classpathInTarget: List) { val mappedClasspath = classpathInHost.mapNotNull { hostLocation -> runCatching { - copyProjectAgnosticPathToTargetIfRequired(Path.of(hostLocation)).asEelPath() + copyProjectSpecificPathToTargetIfRequired(project, Path.of(hostLocation)).asEelPath() }.onFailure { error -> logger.warn("Can't map classpath parameter: $hostLocation", error) }.getOrNull() }.joinToString(eel.platform.pathSeparator) require(classpathInTarget.isEmpty()) {