mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-266058 - fix maven connector spawn for multimodule projects
GitOrigin-RevId: 1eaeb481b3cb559bd26c1163442d2213225a0e79
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c5e725de05
commit
aa07d72bc6
+9
-8
@@ -63,10 +63,11 @@ public class MavenDistributionsCache {
|
||||
}
|
||||
|
||||
public @NotNull String getVmOptions(@Nullable String workingDirectory) {
|
||||
if (!useWrapper() || workingDirectory == null) {
|
||||
return MavenWorkspaceSettingsComponent.getInstance(myProject).getSettings().importingSettings.getVmOptionsForImporter();
|
||||
String vmOptions = MavenWorkspaceSettingsComponent.getInstance(myProject).getSettings().getImportingSettings().getVmOptionsForImporter();
|
||||
if (workingDirectory == null || !StringUtil.isEmptyOrSpaces(vmOptions)) {
|
||||
return vmOptions;
|
||||
}
|
||||
|
||||
|
||||
String multiModuleDir = myWorkingDirToMultimoduleMap.computeIfAbsent(workingDirectory, this::resolveMultimoduleDirectory);
|
||||
return myVmSettingsMap.computeIfAbsent(multiModuleDir, this::readVmOptions);
|
||||
}
|
||||
@@ -74,17 +75,17 @@ public class MavenDistributionsCache {
|
||||
private @NotNull String readVmOptions(@NotNull String multiModuleDir) {
|
||||
MavenWorkspaceSettings settings = MavenWorkspaceSettingsComponent.getInstance(myProject).getSettings();
|
||||
VirtualFile baseDir = LocalFileSystem.getInstance().findFileByPath(multiModuleDir);
|
||||
if (baseDir == null) return settings.importingSettings.getVmOptionsForImporter();
|
||||
if (baseDir == null) return settings.getImportingSettings().getVmOptionsForImporter();
|
||||
VirtualFile mvn = baseDir.findChild(".mvn");
|
||||
if (mvn == null) return settings.importingSettings.getVmOptionsForImporter();
|
||||
if (mvn == null) return settings.getImportingSettings().getVmOptionsForImporter();
|
||||
VirtualFile jdkOpts = mvn.findChild("jvm.config");
|
||||
if (jdkOpts == null) return settings.importingSettings.getVmOptionsForImporter();
|
||||
if (jdkOpts == null) return settings.getImportingSettings().getVmOptionsForImporter();
|
||||
try {
|
||||
return new String(jdkOpts.contentsToByteArray(true), jdkOpts.getCharset());
|
||||
}
|
||||
catch (IOException e) {
|
||||
MavenLog.LOG.warn(e);
|
||||
return settings.importingSettings.getVmOptionsForImporter();
|
||||
return settings.getImportingSettings().getVmOptionsForImporter();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +166,7 @@ public class MavenDistributionsCache {
|
||||
.map(p -> p.getDirectory())
|
||||
.filter(rpDirectory -> FileUtil.isAncestor(rpDirectory, workingDirectory, false))
|
||||
.findFirst()
|
||||
.orElse(workingDirectory));
|
||||
.orElse(calculateMultimoduleDirUpToFileTree(workingDirectory)));
|
||||
}
|
||||
|
||||
private @NotNull String calculateMultimoduleDirUpToFileTree(String directory) {
|
||||
|
||||
+10
-5
@@ -12,7 +12,7 @@ import org.jetbrains.idea.maven.model.MavenModel;
|
||||
|
||||
import java.io.File;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.Collection;
|
||||
import java.util.*;
|
||||
|
||||
public abstract class MavenServerConnector implements @NotNull Disposable {
|
||||
public static final Logger LOG = Logger.getInstance(MavenServerConnector.class);
|
||||
@@ -21,7 +21,7 @@ public abstract class MavenServerConnector implements @NotNull Disposable {
|
||||
protected final MavenServerManager myManager;
|
||||
protected @NotNull final MavenDistribution myDistribution;
|
||||
protected final Sdk myJdk;
|
||||
protected final String myMultimoduleDirectory;
|
||||
protected final Set<String> myMultimoduleDirectories;
|
||||
|
||||
protected final String myVmOptions;
|
||||
|
||||
@@ -36,7 +36,12 @@ public abstract class MavenServerConnector implements @NotNull Disposable {
|
||||
myDistribution = mavenDistribution;
|
||||
myVmOptions = vmOptions;
|
||||
myJdk = jdk;
|
||||
myMultimoduleDirectory = multimoduleDirectory;
|
||||
myMultimoduleDirectories = new LinkedHashSet<>();
|
||||
myMultimoduleDirectories.add(multimoduleDirectory);
|
||||
}
|
||||
|
||||
boolean addMultimoduleDir(String multimoduleDirectory) {
|
||||
return myMultimoduleDirectories.add(multimoduleDirectory);
|
||||
}
|
||||
|
||||
abstract boolean isNew();
|
||||
@@ -132,7 +137,7 @@ public abstract class MavenServerConnector implements @NotNull Disposable {
|
||||
return myProject;
|
||||
}
|
||||
|
||||
public String getMultimoduleDirectory() {
|
||||
return myMultimoduleDirectory;
|
||||
public List<String> getMultimoduleDirectories() {
|
||||
return new ArrayList<>(myMultimoduleDirectories);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -235,7 +235,8 @@ public class MavenServerConnectorImpl extends MavenServerConnector {
|
||||
@Override
|
||||
public void run() {
|
||||
ProgressIndicator indicator = new EmptyProgressIndicator();
|
||||
MavenLog.LOG.info("Connecting maven connector in " + myMultimoduleDirectory);
|
||||
String dirForLogs = myMultimoduleDirectories.iterator().next();
|
||||
MavenLog.LOG.info("Connecting maven connector in " + dirForLogs);
|
||||
try {
|
||||
if (myDebugPort != null) {
|
||||
//noinspection UseOfSystemOutOrSystemErr
|
||||
@@ -253,10 +254,10 @@ public class MavenServerConnectorImpl extends MavenServerConnector {
|
||||
|
||||
server.set(myLogger, myDownloadListener, MavenRemoteObjectWrapper.ourToken);
|
||||
myServerPromise.setResult(server);
|
||||
MavenLog.LOG.info("Connector in " + myMultimoduleDirectory + " has been connected");
|
||||
MavenLog.LOG.info("Connector in " + dirForLogs + " has been connected");
|
||||
}
|
||||
catch (Throwable e) {
|
||||
MavenLog.LOG.warn("Cannot connect connector in " + myMultimoduleDirectory, e);
|
||||
MavenLog.LOG.warn("Cannot connect connector in " + dirForLogs, e);
|
||||
myServerPromise.setError(e);
|
||||
}
|
||||
}
|
||||
|
||||
+52
-15
@@ -62,9 +62,11 @@ public final class MavenServerManager implements Disposable {
|
||||
}
|
||||
|
||||
public Collection<MavenServerConnector> getAllConnectors() {
|
||||
Set<MavenServerConnector> set = Collections.newSetFromMap(new IdentityHashMap<>());
|
||||
synchronized (myMultimoduleDirToConnectorMap) {
|
||||
return new ArrayList<>(myMultimoduleDirToConnectorMap.values());
|
||||
set.addAll(myMultimoduleDirToConnectorMap.values());
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
public void cleanUp(MavenServerConnector connector) {
|
||||
@@ -126,28 +128,60 @@ public final class MavenServerManager implements Disposable {
|
||||
MavenWorkspaceSettings settings = MavenWorkspaceSettingsComponent.getInstance(project).getSettings();
|
||||
Sdk jdk = getJdk(project, settings);
|
||||
|
||||
MavenServerConnector connector;
|
||||
synchronized (myMultimoduleDirToConnectorMap) {
|
||||
connector = myMultimoduleDirToConnectorMap.computeIfAbsent(multimoduleDirectory, dir -> registerNewConnector(project, jdk, multimoduleDirectory));
|
||||
}
|
||||
MavenServerConnector connector = doGetOrCreateConnector(project, multimoduleDirectory, jdk);
|
||||
if(connector.isNew()) {
|
||||
connector.connect();
|
||||
} else {
|
||||
if(!compatibleParameters(project, connector, jdk, multimoduleDirectory)) {
|
||||
if (!compatibleParameters(project, connector, jdk, multimoduleDirectory)) {
|
||||
MavenLog.LOG.info("Maven connector in " + multimoduleDirectory + " is incompatible, restarting");
|
||||
connector.shutdown(false);
|
||||
synchronized (myMultimoduleDirToConnectorMap) {
|
||||
connector = myMultimoduleDirToConnectorMap.computeIfAbsent(multimoduleDirectory, dir -> registerNewConnector(project, jdk, multimoduleDirectory));
|
||||
}
|
||||
connector = this.doGetOrCreateConnector(project, multimoduleDirectory, jdk);
|
||||
connector.connect();
|
||||
}
|
||||
}
|
||||
return connector;
|
||||
}
|
||||
|
||||
private MavenServerConnector registerNewConnector(Project project,
|
||||
Sdk jdk,
|
||||
String multimoduleDirectory) {
|
||||
private MavenServerConnector doGetOrCreateConnector(@NotNull Project project,
|
||||
@NotNull String multimoduleDirectory,
|
||||
@NotNull Sdk jdk) {
|
||||
MavenServerConnector connector;
|
||||
synchronized (myMultimoduleDirToConnectorMap) {
|
||||
connector = myMultimoduleDirToConnectorMap.get(multimoduleDirectory);
|
||||
if (connector != null) return connector;
|
||||
connector = findCompatibleConnector(project, jdk, multimoduleDirectory);
|
||||
if (connector != null) {
|
||||
MavenLog.LOG.info("use existing connector for " + multimoduleDirectory + ":::" + connector.getMultimoduleDirectories());
|
||||
connector.addMultimoduleDir(multimoduleDirectory);
|
||||
}
|
||||
else {
|
||||
connector = registerNewConnector(project, jdk, multimoduleDirectory);
|
||||
}
|
||||
myMultimoduleDirToConnectorMap.put(multimoduleDirectory, connector);
|
||||
}
|
||||
|
||||
return connector;
|
||||
}
|
||||
|
||||
private @Nullable MavenServerConnector findCompatibleConnector(@NotNull Project project,
|
||||
@NotNull Sdk jdk,
|
||||
@NotNull String multimoduleDirectory) {
|
||||
MavenDistribution distribution = MavenDistributionsCache.getInstance(project).getMavenDistribution(multimoduleDirectory);
|
||||
String vmOptions = MavenDistributionsCache.getInstance(project).getVmOptions(multimoduleDirectory);
|
||||
for (Map.Entry<String, MavenServerConnector> entry : myMultimoduleDirToConnectorMap.entrySet()) {
|
||||
if (!entry.getValue().getProject().equals(project)) continue;
|
||||
if (Registry.is("maven.server.per.idea.project")) return entry.getValue();
|
||||
if (entry.getValue().isCompatibleWith(jdk, vmOptions, distribution)) {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private @NotNull MavenServerConnector registerNewConnector(Project project,
|
||||
Sdk jdk,
|
||||
String multimoduleDirectory) {
|
||||
MavenDistribution distribution = MavenDistributionsCache.getInstance(project).getMavenDistribution(multimoduleDirectory);
|
||||
String vmOptions = MavenDistributionsCache.getInstance(project).getVmOptions(multimoduleDirectory);
|
||||
Integer debugPort = getDebugPort(project);
|
||||
@@ -210,7 +244,7 @@ public final class MavenServerManager implements Disposable {
|
||||
MavenServerConnector connector,
|
||||
Sdk jdk,
|
||||
String multimoduleDirectory) {
|
||||
|
||||
if (Registry.is("maven.server.per.idea.project")) return true;
|
||||
MavenDistributionsCache cache = MavenDistributionsCache.getInstance(project);
|
||||
MavenDistribution distribution = cache.getMavenDistribution(multimoduleDirectory);
|
||||
String vmOptions = cache.getVmOptions(multimoduleDirectory);
|
||||
@@ -436,8 +470,11 @@ public final class MavenServerManager implements Disposable {
|
||||
protected MavenServerIndexer create() throws RemoteException {
|
||||
MavenServerConnector connector;
|
||||
synchronized (myMultimoduleDirToConnectorMap) {
|
||||
connector = ContainerUtil.find(myMultimoduleDirToConnectorMap.values(), c -> FileUtil
|
||||
.isAncestor(finalPath, c.getMultimoduleDirectory(), false));
|
||||
connector = ContainerUtil.find(myMultimoduleDirToConnectorMap.values(), c -> ContainerUtil.find(
|
||||
c.myMultimoduleDirectories,
|
||||
mDir -> FileUtil
|
||||
.isAncestor(finalPath, mDir, false)) != null
|
||||
);
|
||||
}
|
||||
if (connector != null) {
|
||||
return connector.createIndexer();
|
||||
|
||||
@@ -49,7 +49,7 @@ class ConnectorTable : ListTableWithButtons<MavenServerConnector>() {
|
||||
val project = TableColumn(MavenConfigurableBundle.message("connector.ui.project")) { it.project.name }
|
||||
val jdk = TableColumn(MavenConfigurableBundle.message("connector.ui.jdk")) { it.jdk.name }
|
||||
val vmopts = TableColumn(MavenConfigurableBundle.message("connector.ui.vmOptions")) { it.vmOptions }
|
||||
val dir = TableColumn(MavenConfigurableBundle.message("connector.ui.dir")) { it.multimoduleDirectory }
|
||||
val dir = TableColumn(MavenConfigurableBundle.message("connector.ui.dir")) { it.multimoduleDirectories.joinToString(separator = ",") }
|
||||
val maven = TableColumn(
|
||||
MavenConfigurableBundle.message("connector.ui.maven")) { "${it.mavenDistribution.version} ${it.mavenDistribution.mavenHome}" }
|
||||
val state = TableColumn(
|
||||
|
||||
+2
-1
@@ -3,9 +3,10 @@ package org.jetbrains.idea.maven.server.ui
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.project.DumbAwareAction
|
||||
import org.jetbrains.idea.maven.statistics.MavenActionsUsagesCollector
|
||||
|
||||
class ShowMavenConnectorsAction : AnAction() {
|
||||
class ShowMavenConnectorsAction : DumbAwareAction() {
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
MavenActionsUsagesCollector.trigger(e.project, MavenActionsUsagesCollector.ActionID.ShowMavenConnectors)
|
||||
MavenConnectorList().show()
|
||||
|
||||
@@ -275,11 +275,17 @@ public class MavenUtil {
|
||||
VirtualFile child = dir.findChild(".mvn");
|
||||
|
||||
if (child != null && child.isDirectory()) {
|
||||
if (MavenLog.LOG.isDebugEnabled()) {
|
||||
MavenLog.LOG.debug("found .mvn in " + child);
|
||||
}
|
||||
baseDir = dir;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while ((dir = dir.getParent()) != null);
|
||||
if (MavenLog.LOG.isDebugEnabled()) {
|
||||
MavenLog.LOG.debug("return " + baseDir + " as baseDir");
|
||||
}
|
||||
return baseDir;
|
||||
}
|
||||
|
||||
|
||||
@@ -253,8 +253,11 @@
|
||||
<registryKey key="maven.import.compiler.arguments" defaultValue="true"
|
||||
description="Enable importing of the maven compiler plugin arguments"/>
|
||||
|
||||
<registryKey key="maven.server.per.idea.project" defaultValue="false"
|
||||
description="Single Maven server per idea project, .mvn could be ignored"/>
|
||||
|
||||
<registryKey key="maven.always.reset" defaultValue="false"
|
||||
description="always reset maven dependencies and folders"/>
|
||||
description="Always reset maven dependencies and folders"/>
|
||||
|
||||
<registryKey key="maven.print.import.stacktraces" defaultValue="false"
|
||||
description="Print maven server stacktraces in log"/>
|
||||
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
// Copyright 2000-2021 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.
|
||||
package org.jetbrains.idea.maven.importing
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.idea.maven.MavenImportingTestCase
|
||||
import org.jetbrains.idea.maven.server.MavenServerManager
|
||||
import org.jetbrains.idea.maven.wizards.MavenOpenProjectProvider
|
||||
import java.io.File
|
||||
|
||||
class MavenImportingConnectorsTest : MavenImportingTestCase() {
|
||||
protected lateinit var myAnotherProjectRoot: VirtualFile
|
||||
|
||||
@Throws(Exception::class)
|
||||
override fun setUpInWriteAction() {
|
||||
super.setUpInWriteAction()
|
||||
val projectDir = File(myDir, "anotherProject")
|
||||
projectDir.mkdirs()
|
||||
myAnotherProjectRoot = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(projectDir)!!
|
||||
}
|
||||
|
||||
fun testShouldNotCreateNewConnectorForNewProject() {
|
||||
createProjectPom("<groupId>test</groupId>" +
|
||||
"<artifactId>project1</artifactId>" +
|
||||
"<version>1</version>" +
|
||||
"<packaging>pom</packaging>" +
|
||||
"<modules>" +
|
||||
"<module>m1</module>" +
|
||||
" </modules>")
|
||||
createModulePom("m1", "<groupId>test</groupId>" +
|
||||
"<artifactId>m1</artifactId>" +
|
||||
"<version>1</version>")
|
||||
importProject()
|
||||
assertModules("project1", "m1")
|
||||
val p2Root = createPomFile(myAnotherProjectRoot, "<groupId>test</groupId>" +
|
||||
"<artifactId>project2</artifactId>" +
|
||||
"<version>1</version>" +
|
||||
"<packaging>pom</packaging>" +
|
||||
"<modules>" +
|
||||
"<module>m2</module>" +
|
||||
" </modules>")
|
||||
createModulePom("../anotherProject/m2", "<groupId>test</groupId>" +
|
||||
"<artifactId>m2</artifactId>" +
|
||||
"<version>2</version>")
|
||||
MavenOpenProjectProvider().linkToExistingProject(p2Root, myProject)
|
||||
assertModules("project1", "m1", "project2", "m2")
|
||||
assertEquals(1, MavenServerManager.getInstance().allConnectors.size);
|
||||
|
||||
assertUnorderedElementsAreEqual(
|
||||
MavenServerManager.getInstance().allConnectors.first().multimoduleDirectories.map {
|
||||
FileUtil.getRelativePath(myDir, File(it))
|
||||
},
|
||||
listOf("project", "anotherProject")
|
||||
)
|
||||
}
|
||||
|
||||
fun testShouldCreateNewConnectorForNewProjectIfJvmConfigPresents() {
|
||||
createProjectPom("<groupId>test</groupId>" +
|
||||
"<artifactId>project1</artifactId>" +
|
||||
"<version>1</version>" +
|
||||
"<packaging>pom</packaging>" +
|
||||
"<modules>" +
|
||||
"<module>m1</module>" +
|
||||
" </modules>")
|
||||
createModulePom("m1", "<groupId>test</groupId>" +
|
||||
"<artifactId>m1</artifactId>" +
|
||||
"<version>1</version>")
|
||||
importProject()
|
||||
assertModules("project1", "m1")
|
||||
val p2Root = createPomFile(myAnotherProjectRoot, "<groupId>test</groupId>" +
|
||||
"<artifactId>project2</artifactId>" +
|
||||
"<version>1</version>" +
|
||||
"<packaging>pom</packaging>" +
|
||||
"<modules>" +
|
||||
"<module>m2</module>" +
|
||||
" </modules>")
|
||||
createModulePom("../anotherProject/m2", "<groupId>test</groupId>" +
|
||||
"<artifactId>m2</artifactId>" +
|
||||
"<version>2</version>")
|
||||
|
||||
createProjectSubFile("../anotherProject/.mvn/jvm.config", "-Dsomething=blablabla")
|
||||
MavenOpenProjectProvider().linkToExistingProject(p2Root, myProject)
|
||||
assertModules("project1", "m1", "project2", "m2")
|
||||
|
||||
assertEquals(2, MavenServerManager.getInstance().allConnectors.size);
|
||||
|
||||
assertUnorderedElementsAreEqual(
|
||||
MavenServerManager.getInstance().allConnectors.map {
|
||||
FileUtil.getRelativePath(myDir, File(it.multimoduleDirectories.first()))
|
||||
},
|
||||
listOf("project", "anotherProject")
|
||||
)
|
||||
}
|
||||
|
||||
fun testShouldNotCreateNewConnectorForNewProjectIfJvmConfigPresentsAndRegistrySet() {
|
||||
createProjectPom("<groupId>test</groupId>" +
|
||||
"<artifactId>project1</artifactId>" +
|
||||
"<version>1</version>" +
|
||||
"<packaging>pom</packaging>" +
|
||||
"<modules>" +
|
||||
"<module>m1</module>" +
|
||||
" </modules>")
|
||||
createModulePom("m1", "<groupId>test</groupId>" +
|
||||
"<artifactId>m1</artifactId>" +
|
||||
"<version>1</version>")
|
||||
importProject()
|
||||
assertModules("project1", "m1")
|
||||
val p2Root = createPomFile(myAnotherProjectRoot, "<groupId>test</groupId>" +
|
||||
"<artifactId>project2</artifactId>" +
|
||||
"<version>1</version>" +
|
||||
"<packaging>pom</packaging>" +
|
||||
"<modules>" +
|
||||
"<module>m2</module>" +
|
||||
" </modules>")
|
||||
createModulePom("../anotherProject/m2", "<groupId>test</groupId>" +
|
||||
"<artifactId>m2</artifactId>" +
|
||||
"<version>2</version>")
|
||||
|
||||
createProjectSubFile("../anotherProject/.mvn/jvm.config", "-Dsomething=blablabla")
|
||||
val value = Registry.`is`("maven.server.per.idea.project")
|
||||
try {
|
||||
Registry.get("maven.server.per.idea.project").setValue(true);
|
||||
MavenOpenProjectProvider().linkToExistingProject(p2Root, myProject)
|
||||
assertModules("project1", "m1", "project2", "m2")
|
||||
|
||||
assertEquals(1, MavenServerManager.getInstance().allConnectors.size);
|
||||
|
||||
assertUnorderedElementsAreEqual(
|
||||
MavenServerManager.getInstance().allConnectors.first().multimoduleDirectories.map {
|
||||
FileUtil.getRelativePath(myDir, File(it))
|
||||
},
|
||||
listOf("project", "anotherProject")
|
||||
)
|
||||
}
|
||||
finally {
|
||||
Registry.get("maven.server.per.idea.project").setValue(value)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user