diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenExecutionContext.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenExecutionContext.java index a6e1e764aa..1a5c88ce21 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenExecutionContext.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenExecutionContext.java @@ -17,6 +17,7 @@ import static org.eclipse.m2e.core.internal.M2EUtils.copyProperties; import java.io.File; +import java.io.IOException; import java.util.ArrayDeque; import java.util.Collections; import java.util.Deque; @@ -25,6 +26,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Properties; import java.util.Set; import java.util.function.Function; @@ -73,6 +75,7 @@ import org.eclipse.m2e.core.embedder.IComponentLookup; import org.eclipse.m2e.core.embedder.IMavenConfiguration; import org.eclipse.m2e.core.embedder.IMavenExecutionContext; +import org.eclipse.m2e.core.embedder.MavenSettingsLocations; import org.eclipse.m2e.core.internal.MavenPluginActivator; import org.eclipse.m2e.core.internal.Messages; @@ -149,32 +152,59 @@ protected MavenExecutionRequest newExecutionRequest() throws CoreException { } request = DefaultMavenExecutionRequest.copy(parent); } - if(request == null) { - request = createExecutionRequest(IMavenConfiguration.getWorkspaceConfiguration(), - containerLookup, MavenPlugin.getMaven().getSettings()); - request.setBaseDirectory(basedir); + if(request == null || !Objects.equals(request.getMultiModuleProjectDirectory(), multiModuleProjectDirectory)) { + IMavenConfiguration workspaceConfiguration = IMavenConfiguration.getWorkspaceConfiguration(); + Optional mavenArgs; + try { + mavenArgs = MavenProperties.getMavenArgs(multiModuleProjectDirectory); + } catch(IOException ex) { + throw new CoreException(Status.error("Loading maven.config failed!", ex)); + } + MavenSettingsLocations mavenSettingsLocations = mavenArgs + .map(mavenCfg -> mavenCfg.getSettingsLocations(workspaceConfiguration)) + .orElseGet(workspaceConfiguration::getSettingsLocations); + if(request == null) { + //create a fresh one .... + request = createExecutionRequest(workspaceConfiguration, containerLookup, mavenSettingsLocations); + request.setBaseDirectory(basedir); + } else { + //update existing configuration, we might have copied from an outer context here but the multi module directory is different we need to update some things then... + Settings settings = MavenPlugin.getMaven().getSettings(mavenSettingsLocations); + File requestLocalRepositoryPath = request.getLocalRepositoryPath(); + File settingsLocalRepositoryPath = getLocalRepositoryPath(settings); + if(!pathEquals(requestLocalRepositoryPath, settingsLocalRepositoryPath)) { + updateLocalRepository(request, settingsLocalRepositoryPath, containerLookup); + } + //TODO maybe also need to update user properties?!? + updateSettingsFiles(request, mavenSettingsLocations); + } + request.setMultiModuleProjectDirectory(multiModuleProjectDirectory); } - request.setMultiModuleProjectDirectory(multiModuleProjectDirectory); - return request; } + private boolean pathEquals(File file1, File file2) { + if(file1 != null && file2 != null) { + if(Objects.equals(file1, file2)) { + return true; + } + try { + return Objects.equals(file1.getCanonicalFile(), file2.getCanonicalFile()); + } catch(IOException ex) { + //can't compare then... + } + } + return false; + } + static MavenExecutionRequest createExecutionRequest(IMavenConfiguration mavenConfiguration, IComponentLookup lookup, - Settings settings) throws CoreException { + MavenSettingsLocations settingsLocations) throws CoreException { MavenExecutionRequest request = new DefaultMavenExecutionRequest(); - // this causes problems with unexpected "stale project configuration" error markers // need to think how to manage ${maven.build.timestamp} properly inside workspace //request.setStartTime( new Date() ); - - if(mavenConfiguration.getGlobalSettingsFile() != null) { - request.setGlobalSettingsFile(new File(mavenConfiguration.getGlobalSettingsFile())); - } - File userSettingsFile = SettingsXmlConfigurationProcessor.DEFAULT_USER_SETTINGS_FILE; - if(mavenConfiguration.getUserSettingsFile() != null) { - userSettingsFile = new File(mavenConfiguration.getUserSettingsFile()); - } - request.setUserSettingsFile(userSettingsFile); + Settings settings = MavenPlugin.getMaven().getSettings(settingsLocations); + updateSettingsFiles(request, settingsLocations); //and settings are actually derived from IMavenConfiguration @@ -183,26 +213,13 @@ static MavenExecutionRequest createExecutionRequest(IMavenConfiguration mavenCon userToolchainsFile = new File(mavenConfiguration.getUserToolchainsFile()); } request.setUserToolchainsFile(userToolchainsFile); - try { request = lookup.lookup(MavenExecutionRequestPopulator.class).populateFromSettings(request, settings); } catch(MavenExecutionRequestPopulationException ex) { throw new CoreException(Status.error(Messages.MavenImpl_error_no_exec_req, ex)); } - String localRepositoryPath = settings.getLocalRepository(); - if(localRepositoryPath == null) { - localRepositoryPath = RepositorySystem.defaultUserLocalRepository.getAbsolutePath(); - } - - ArtifactRepository localRepository; - try { - localRepository = lookup.lookup(RepositorySystem.class).createLocalRepository(new File(localRepositoryPath)); - } catch(InvalidRepositoryException ex) { - throw new AssertionError("Should never happen!", ex); - } - request.setLocalRepository(localRepository); - request.setLocalRepositoryPath(localRepository.getBasedir()); + updateLocalRepository(request, getLocalRepositoryPath(settings), lookup); request.setOffline(mavenConfiguration.isOffline()); request.getUserProperties().put("m2e.version", MavenPluginActivator.getVersion()); //$NON-NLS-1$ @@ -217,6 +234,39 @@ static MavenExecutionRequest createExecutionRequest(IMavenConfiguration mavenCon return request; } + private static void updateSettingsFiles(MavenExecutionRequest request, MavenSettingsLocations settingsLocations) { + File global = settingsLocations.globalSettings(); + if(global != null) { + request.setGlobalSettingsFile(global); + } + File userSettingsFile = settingsLocations.userSettings(); + if(userSettingsFile == null) { + request.setUserSettingsFile(SettingsXmlConfigurationProcessor.DEFAULT_USER_SETTINGS_FILE); + } else { + request.setUserSettingsFile(userSettingsFile); + } + } + + private static void updateLocalRepository(MavenExecutionRequest request, File localRepositoryPath, + IComponentLookup lookup) throws CoreException, AssertionError { + ArtifactRepository localRepository; + try { + localRepository = lookup.lookup(RepositorySystem.class).createLocalRepository(localRepositoryPath); + } catch(InvalidRepositoryException ex) { + throw new AssertionError("Should never happen!", ex); + } + request.setLocalRepository(localRepository); + request.setLocalRepositoryPath(localRepository.getBasedir()); + } + + private static File getLocalRepositoryPath(Settings settings) { + String localRepositoryPath = settings.getLocalRepository(); + if(localRepositoryPath == null) { + return RepositorySystem.defaultUserLocalRepository; + } + return new File(localRepositoryPath); + } + @Override public V execute(ICallable callable, IProgressMonitor monitor) throws CoreException { return execute(null, callable, monitor); diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenProperties.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenProperties.java index d550a058a1..24ae2c351f 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenProperties.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenProperties.java @@ -52,6 +52,9 @@ import org.apache.maven.cli.MavenCli; import org.apache.maven.shared.utils.StringUtils; +import org.eclipse.m2e.core.embedder.IMavenConfiguration; +import org.eclipse.m2e.core.embedder.MavenSettingsLocations; + /** * Holds Maven Runtime version properties. @@ -319,6 +322,30 @@ public String getAlternateUserToolchainsFile() { return null; } + public MavenSettingsLocations getSettingsLocations(IMavenConfiguration configuration) { + MavenSettingsLocations configurationLocations = configuration.getSettingsLocations(); + String alternateGlobalSettingsFile = getAlternateGlobalSettingsFile(); + String alternateUserSettingsFile = getAlternateUserSettingsFile(); + if(alternateGlobalSettingsFile == null && alternateUserSettingsFile == null) { + return configurationLocations; + } + File global; + File user; + //actually maven uses "the current working directory" but this does not make much sense in the context of m2e so we choose the root directory of the maven.config + File baseDir = configFile.getParentFile().getParentFile(); + if(alternateGlobalSettingsFile == null) { + global = configurationLocations.globalSettings(); + } else { + global = new File(baseDir, alternateGlobalSettingsFile); + } + if(alternateUserSettingsFile == null) { + user = configurationLocations.userSettings(); + } else { + user = new File(baseDir, alternateUserSettingsFile); + } + return new MavenSettingsLocations(global, user); + } + public static void getCliProperty(String property, BiConsumer consumer) { int index = property.indexOf('='); if(index <= 0) { diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/PlexusContainerManager.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/PlexusContainerManager.java index 9acf22b5bd..3280d68b09 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/PlexusContainerManager.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/PlexusContainerManager.java @@ -70,7 +70,6 @@ import org.eclipse.m2e.core.embedder.IComponentLookup; import org.eclipse.m2e.core.embedder.IMavenConfiguration; -import org.eclipse.m2e.core.internal.MavenPluginActivator; import org.eclipse.m2e.core.internal.Messages; @@ -343,12 +342,14 @@ protected void configure() { container.setLookupRealm(null); container.setLoggerManager(loggerManager); thread.setContextClassLoader(container.getContainerRealm()); + Optional mavenProperties = MavenProperties.getMavenArgs(multiModuleProjectDirectory); + IMavenConfiguration workspaceConfiguration = IMavenConfiguration.getWorkspaceConfiguration(); MavenExecutionRequest request = MavenExecutionContext.createExecutionRequest(mavenConfiguration, - wrap(container), MavenPluginActivator.getDefault().getMaven().getSettings()); + wrap(container), mavenProperties.map(mavenCfg -> mavenCfg.getSettingsLocations(workspaceConfiguration)) + .orElseGet(workspaceConfiguration::getSettingsLocations)); container.lookup(MavenExecutionRequestPopulator.class).populateDefaults(request); request.setBaseDirectory(multiModuleProjectDirectory); request.setMultiModuleProjectDirectory(multiModuleProjectDirectory); - Optional mavenProperties = MavenProperties.getMavenArgs(multiModuleProjectDirectory); Properties userProperties = request.getUserProperties(); mavenProperties.ifPresent(prop -> prop.getCliProperties(userProperties::setProperty)); BootstrapCoreExtensionManager resolver = container.lookup(BootstrapCoreExtensionManager.class);