diff --git a/java/compiler/impl/intellij.java.compiler.impl.iml b/java/compiler/impl/intellij.java.compiler.impl.iml
index 67db63ddd429..db349a6e6bde 100644
--- a/java/compiler/impl/intellij.java.compiler.impl.iml
+++ b/java/compiler/impl/intellij.java.compiler.impl.iml
@@ -8,13 +8,11 @@
-
-
@@ -25,30 +23,33 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
index 55b8a7ba10dd..6d730782d68b 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
@@ -124,11 +124,9 @@ public final class CompileDriver {
buildManager.postponeBackgroundTasks();
buildManager.cancelAutoMakeTasks(myProject);
TaskFuture> future = compileInExternalProcess(compileContext, true);
- if (future != null) {
- while (!future.waitFor(200L, TimeUnit.MILLISECONDS)) {
- if (indicator.isCanceled()) {
- future.cancel(false);
- }
+ while (!future.waitFor(200L, TimeUnit.MILLISECONDS)) {
+ if (indicator.isCanceled()) {
+ future.cancel(false);
}
}
}
@@ -221,7 +219,7 @@ public final class CompileDriver {
return scopes;
}
- @Nullable
+ @NotNull
private TaskFuture> compileInExternalProcess(@NotNull final CompileContextImpl compileContext, final boolean onlyCheckUpToDate) {
final CompileScope scope = compileContext.getCompileScope();
final Collection paths = ReadAction.compute(() -> CompileScopeUtil.fetchFiles(compileContext));
@@ -450,21 +448,19 @@ public final class CompileDriver {
}
TaskFuture> future = compileInExternalProcess(compileContext, false);
- if (future != null) {
- Tracer.Span compileInExternalProcessSpan = Tracer.start("compile in external process");
- while (!future.waitFor(200L, TimeUnit.MILLISECONDS)) {
- if (indicator.isCanceled()) {
- future.cancel(false);
- }
- }
- compileInExternalProcessSpan.complete();
- if (!executeCompileTasks(compileContext, false)) {
- COMPILE_SERVER_BUILD_STATUS.set(compileContext, ExitStatus.CANCELLED);
- }
- if (compileContext.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
- COMPILE_SERVER_BUILD_STATUS.set(compileContext, ExitStatus.ERRORS);
+ Tracer.Span compileInExternalProcessSpan = Tracer.start("compile in external process");
+ while (!future.waitFor(200L, TimeUnit.MILLISECONDS)) {
+ if (indicator.isCanceled()) {
+ future.cancel(false);
}
}
+ compileInExternalProcessSpan.complete();
+ if (!executeCompileTasks(compileContext, false)) {
+ COMPILE_SERVER_BUILD_STATUS.set(compileContext, ExitStatus.CANCELLED);
+ }
+ if (compileContext.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
+ COMPILE_SERVER_BUILD_STATUS.set(compileContext, ExitStatus.ERRORS);
+ }
}
catch (ProcessCanceledException ignored) {
compileContext.putUserDataIfAbsent(COMPILE_SERVER_BUILD_STATUS, ExitStatus.CANCELLED);
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 4ddd269acfa9..09cf1f18893f 100644
--- a/java/compiler/impl/src/com/intellij/compiler/server/BuildCommandLineBuilder.java
+++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildCommandLineBuilder.java
@@ -1,4 +1,4 @@
-// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.compiler.server;
import com.intellij.compiler.YourKitProfilerService;
@@ -6,7 +6,6 @@ import com.intellij.execution.ExecutionException;
import com.intellij.execution.configurations.GeneralCommandLine;
import org.jetbrains.annotations.NotNull;
-import java.net.InetAddress;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.List;
@@ -27,11 +26,6 @@ interface BuildCommandLineBuilder {
@NotNull
Path getHostWorkingDirectory();
- InetAddress getListenAddress();
-
- @NotNull
- String getHostIp() throws ExecutionException;
-
String getYjpAgentPath(YourKitProfilerService yourKitProfilerService);
void setCharset(Charset charset);
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 3b3be268614b..2fa8d445387b 100644
--- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
+++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
@@ -23,6 +23,7 @@ import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.wsl.WSLDistribution;
import com.intellij.execution.wsl.WslDistributionManager;
import com.intellij.execution.wsl.WslPath;
+import com.intellij.execution.wsl.WslProxy;
import com.intellij.ide.IdleTracker;
import com.intellij.ide.PowerSaveMode;
import com.intellij.ide.actions.RevealFileAction;
@@ -287,6 +288,7 @@ public final class BuildManager implements Disposable {
}
private final List myListeningConnections = new ArrayList<>();
+ private final Map myWslProxyCache = new HashMap<>();
private final @NotNull Charset mySystemCharset = CharsetToolkit.getDefaultSystemCharset();
private volatile boolean myBuildProcessDebuggingEnabled;
@@ -406,7 +408,10 @@ public final class BuildManager implements Disposable {
});
}
- ShutDownTracker.getInstance().registerShutdownTask(this::stopListening);
+ ShutDownTracker.getInstance().registerShutdownTask(() -> {
+ stopListening();
+ clearWslProxyCache();
+ });
if (!IS_UNIT_TEST_MODE) {
ScheduledFuture> future = AppExecutorUtil.getAppScheduledExecutorService().scheduleWithFixedDelay(() -> runCommand(myGCTask), 3, 180, TimeUnit.MINUTES);
@@ -716,10 +721,8 @@ public final class BuildManager implements Disposable {
final TaskFuture> future = scheduleBuild(
project, false, true, false, scopes, Collections.emptyList(), Collections.singletonMap(BuildParametersKeys.IS_AUTOMAKE, "true"), handler
);
- if (future != null) {
- myAutomakeFutures.put(future, project);
- futures.add(new Pair<>(future, handler));
- }
+ myAutomakeFutures.put(future, project);
+ futures.add(new Pair<>(future, handler));
}
boolean needAdditionalBuild = false;
for (Pair, AutoMakeMessageHandler> pair : futures) {
@@ -862,7 +865,7 @@ public final class BuildManager implements Disposable {
return result != null && !result.first.isDone()? result : null;
}
- public @Nullable TaskFuture> scheduleBuild(
+ public @NotNull TaskFuture> scheduleBuild(
final Project project, final boolean isRebuild, final boolean isMake,
final boolean onlyCheckUpToDate, final List scopes,
final Collection paths,
@@ -873,15 +876,6 @@ public final class BuildManager implements Disposable {
final boolean isAutomake = messageHandler instanceof AutoMakeMessageHandler;
final WSLDistribution wslDistribution = findWSLDistribution(project);
final BuilderMessageHandler handler = new NotifyingMessageHandler(project, messageHandler, wslDistribution != null ? wslDistribution::getWindowsPath : null, isAutomake);
- try {
- ensureListening(wslDistribution != null ? wslDistribution.getHostIpAddress() : InetAddress.getLoopbackAddress());
- }
- catch (Exception e) {
- final UUID sessionId = UUID.randomUUID(); // the actual session did not start; use random UUID
- handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), null));
- handler.sessionTerminated(sessionId);
- return null;
- }
Function pathMapper = wslDistribution != null ? wslDistribution::getWslPath : Function.identity();
final DelegateFuture _future = new DelegateFuture();
@@ -1128,9 +1122,30 @@ public final class BuildManager implements Disposable {
return startListening(inetAddress);
}
+ private synchronized int getWslPort(WSLDistribution dist, int localPort) {
+ return myWslProxyCache.computeIfAbsent(dist.getId() + ":" + localPort, key -> new WslProxy(dist, localPort)).getWslIngressPort();
+ }
+
+ private synchronized void cleanWslProxies(WSLDistribution dist) {
+ String idPrefix = dist.getId() + ":";
+ List keys = new SmartList<>();
+ for (String key : myWslProxyCache.keySet()) {
+ if (key.startsWith(idPrefix)) {
+ keys.add(key);
+ }
+ }
+ for (String key : keys) {
+ WslProxy proxy = myWslProxyCache.remove(key);
+ if (proxy != null) {
+ Disposer.dispose(proxy);
+ }
+ }
+ }
+
@Override
public void dispose() {
stopListening();
+ clearWslProxyCache();
myAutomakeTrigger.cancel();
myRequestsProcessor.cancel();
}
@@ -1323,6 +1338,11 @@ public final class BuildManager implements Disposable {
final CompilerConfiguration projectConfig = CompilerConfiguration.getInstance(project);
final CompilerWorkspaceConfiguration config = CompilerWorkspaceConfiguration.getInstance(project);
+ InetAddress listenAddress = InetAddress.getLoopbackAddress();
+ int listenPort = ensureListening(listenAddress);
+ String buildProcessConnectHost = listenAddress.getHostAddress();
+ int buildProcessConnectPort = listenPort;
+
BuildCommandLineBuilder cmdLine;
WslPath wslPath = WslPath.parseWindowsUncPath(vmExecutablePath);
if (wslPath != null) {
@@ -1331,6 +1351,8 @@ public final class BuildManager implements Disposable {
throw new ExecutionException(JavaCompilerBundle.message("build.process.wsl.distribution.dont.match", sdkName + " (WSL " + sdkDistribution.getPresentableName() + ")", MINIMUM_REQUIRED_JPS_BUILD_JAVA_VERSION));
}
cmdLine = new WslBuildCommandLineBuilder(project, sdkDistribution, wslPath.getLinuxPath(), progressIndicator);
+ buildProcessConnectHost = "127.0.0.1"; // WslProxy listen address on linux side
+ buildProcessConnectPort = getWslPort(sdkDistribution, listenPort);
}
else {
if (projectWslDistribution != null) {
@@ -1338,7 +1360,6 @@ public final class BuildManager implements Disposable {
}
cmdLine = new LocalBuildCommandLineBuilder(vmExecutablePath);
}
- int listenPort = ensureListening(cmdLine.getListenAddress());
boolean profileWithYourKit = false;
boolean isAgentpathSet = false;
@@ -1612,8 +1633,8 @@ public final class BuildManager implements Disposable {
}
cmdLine.addParameter(BuildMain.class.getName());
- cmdLine.addParameter(cmdLine.getHostIp());
- cmdLine.addParameter(Integer.toString(listenPort));
+ cmdLine.addParameter(buildProcessConnectHost);
+ cmdLine.addParameter(Integer.toString(buildProcessConnectPort));
cmdLine.addParameter(sessionId.toString());
cmdLine.addParameter(cmdLine.getWorkingDirectory());
@@ -1782,13 +1803,24 @@ public final class BuildManager implements Disposable {
return null;
}
- private void stopListening() {
+ private synchronized void stopListening() {
for (ListeningConnection connection : myListeningConnections) {
connection.myChannelRegistrar.close();
}
myListeningConnections.clear();
}
+ private synchronized void clearWslProxyCache() {
+ for (WslProxy proxy : myWslProxyCache.values()) {
+ try {
+ Disposer.dispose(proxy);
+ }
+ catch (Throwable ignored) {
+ }
+ }
+ myWslProxyCache.clear();
+ }
+
private int startListening(InetAddress address) {
ListeningConnection listeningConnection = new ListeningConnection(address);
BuiltInServerManager builtInServerManager = BuiltInServerManager.getInstance();
@@ -2193,6 +2225,10 @@ public final class BuildManager implements Disposable {
}
}
});
+ WSLDistribution wslDistr = findWSLDistribution(project);
+ if (wslDistr != null) {
+ cleanWslProxies(wslDistr);
+ }
}
@Override
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/LocalBuildCommandLineBuilder.java b/java/compiler/impl/src/com/intellij/compiler/server/LocalBuildCommandLineBuilder.java
index 21b493c7f1a8..abc678366aed 100644
--- a/java/compiler/impl/src/com/intellij/compiler/server/LocalBuildCommandLineBuilder.java
+++ b/java/compiler/impl/src/com/intellij/compiler/server/LocalBuildCommandLineBuilder.java
@@ -10,7 +10,6 @@ import com.intellij.openapi.util.io.FileUtilRt;
import org.jetbrains.annotations.NotNull;
import java.io.File;
-import java.net.InetAddress;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.List;
@@ -62,16 +61,6 @@ final class LocalBuildCommandLineBuilder implements BuildCommandLineBuilder {
return getLocalBuildSystemDirectory();
}
- @Override
- public InetAddress getListenAddress() {
- return InetAddress.getLoopbackAddress();
- }
-
- @Override
- public @NotNull String getHostIp() {
- return getListenAddress().getHostAddress();
- }
-
@Override
public String getYjpAgentPath(YourKitProfilerService yourKitProfilerService) {
return getLocalBuildSystemDirectory()
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/WslBuildCommandLineBuilder.java b/java/compiler/impl/src/com/intellij/compiler/server/WslBuildCommandLineBuilder.java
index 5145f376597e..f5aca41f9a96 100644
--- a/java/compiler/impl/src/com/intellij/compiler/server/WslBuildCommandLineBuilder.java
+++ b/java/compiler/impl/src/com/intellij/compiler/server/WslBuildCommandLineBuilder.java
@@ -20,7 +20,6 @@ import org.jetbrains.jps.api.GlobalOptions;
import java.io.FileNotFoundException;
import java.io.IOException;
-import java.net.InetAddress;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
@@ -43,8 +42,7 @@ final class WslBuildCommandLineBuilder implements BuildCommandLineBuilder {
private static boolean CURRENT_SNAPSHOT_COPIED = false;
private boolean myReportedProgress;
- WslBuildCommandLineBuilder(@NotNull Project project, @NotNull WSLDistribution distribution, @NotNull String sdkPath,
- @Nullable ProgressIndicator progressIndicator) {
+ WslBuildCommandLineBuilder(@NotNull Project project, @NotNull WSLDistribution distribution, @NotNull String sdkPath, @Nullable ProgressIndicator progressIndicator) {
myProject = project;
myDistribution = distribution;
myProgressIndicator = progressIndicator;
@@ -156,21 +154,6 @@ final class WslBuildCommandLineBuilder implements BuildCommandLineBuilder {
return myWorkingDirectory;
}
- @Override
- public InetAddress getListenAddress() {
- try {
- return myDistribution.getHostIpAddress();
- }
- catch (ExecutionException ignored) {
- return null;
- }
- }
-
- @Override
- public @NotNull String getHostIp() throws ExecutionException {
- return myDistribution.getHostIpAddress().getHostAddress();
- }
-
@Override
public String getYjpAgentPath(YourKitProfilerService yourKitProfilerService) {
return myWorkingDirectory + "/" + yourKitProfilerService.getYKAgentFullNameForWSL();