You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by rf...@apache.org on 2014/12/25 14:55:26 UTC

maven git commit: [MNG-3891] Modify maven-toolchain to look in ${maven.home}/conf/toolchains.xml and in ${user.home}/.m2/toolchains.xml Also added new cmdline option: -gt / --global-toolchains

Repository: maven
Updated Branches:
  refs/heads/master 226e6385d -> ceae92265


[MNG-3891] Modify maven-toolchain to look in ${maven.home}/conf/toolchains.xml and in ${user.home}/.m2/toolchains.xml
Also added new cmdline option: -gt / --global-toolchains


Project: http://git-wip-us.apache.org/repos/asf/maven/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven/commit/ceae9226
Tree: http://git-wip-us.apache.org/repos/asf/maven/tree/ceae9226
Diff: http://git-wip-us.apache.org/repos/asf/maven/diff/ceae9226

Branch: refs/heads/master
Commit: ceae922653e7bf4bd1013e01d0f8deae7443744c
Parents: 226e638
Author: Robert Scholte <rf...@codehaus.org>
Authored: Thu Dec 25 14:55:02 2014 +0100
Committer: Robert Scholte <rf...@codehaus.org>
Committed: Thu Dec 25 14:55:02 2014 +0100

----------------------------------------------------------------------
 .../org/apache/maven/building/FileSource.java   |   2 +-
 .../execution/DefaultMavenExecutionRequest.java |  16 +++
 .../maven/execution/MavenExecutionRequest.java  |  16 +++
 .../DefaultToolchainManagerPrivate.java         |  34 ++++-
 .../toolchain/DefaultToolchainsBuilder.java     |   3 +
 .../building/DefaultToolchainsBuilder.java      | 136 +++++++++++++++++++
 .../DefaultToolchainsBuildingRequest.java       |  63 +++++++++
 .../DefaultToolchainsBuildingResult.java        |  59 ++++++++
 .../toolchain/building/ToolchainsBuilder.java   |  41 ++++++
 .../building/ToolchainsBuildingException.java   |  88 ++++++++++++
 .../building/ToolchainsBuildingRequest.java     |  64 +++++++++
 .../building/ToolchainsBuildingResult.java      |  50 +++++++
 .../building/io/DefaultToolchainsReader.java    | 115 ++++++++++++++++
 .../building/io/ToolchainsParseException.java   |  94 +++++++++++++
 .../toolchain/building/io/ToolchainsReader.java |  83 +++++++++++
 .../java/org/apache/maven/cli/CLIManager.java   |   3 +
 .../java/org/apache/maven/cli/MavenCli.java     |  66 ++++++++-
 17 files changed, 925 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven/blob/ceae9226/maven-builder-support/src/main/java/org/apache/maven/building/FileSource.java
----------------------------------------------------------------------
diff --git a/maven-builder-support/src/main/java/org/apache/maven/building/FileSource.java b/maven-builder-support/src/main/java/org/apache/maven/building/FileSource.java
index b201ee6..1a6fc2f 100644
--- a/maven-builder-support/src/main/java/org/apache/maven/building/FileSource.java
+++ b/maven-builder-support/src/main/java/org/apache/maven/building/FileSource.java
@@ -43,7 +43,7 @@ public class FileSource
     {
         if ( file == null )
         {
-            throw new IllegalArgumentException( "no POM file specified" );
+            throw new IllegalArgumentException( "no file specified" );
         }
         this.file = file.getAbsoluteFile();
     }

http://git-wip-us.apache.org/repos/asf/maven/blob/ceae9226/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java b/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java
index df91f82..933e168 100644
--- a/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java
+++ b/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java
@@ -84,6 +84,8 @@ public class DefaultMavenExecutionRequest
 
     private File userToolchainsFile;
 
+    private File globalToolchainsFile;
+
     // ----------------------------------------------------------------------------
     // Request
     // ----------------------------------------------------------------------------
@@ -169,6 +171,7 @@ public class DefaultMavenExecutionRequest
         copy.setUserSettingsFile( original.getUserSettingsFile() );
         copy.setGlobalSettingsFile( original.getGlobalSettingsFile() );
         copy.setUserToolchainsFile( original.getUserToolchainsFile() );
+        copy.setGlobalToolchainsFile( original.getGlobalToolchainsFile() );
         copy.setBaseDirectory( ( original.getBaseDirectory() != null ) ? new File( original.getBaseDirectory() ) : null );
         copy.setGoals( original.getGoals() );
         copy.setRecursive( original.isRecursive() );
@@ -931,6 +934,19 @@ public class DefaultMavenExecutionRequest
 
         return this;
     }
+    
+    @Override
+    public File getGlobalToolchainsFile()
+    {
+        return globalToolchainsFile;
+    }
+    
+    @Override
+    public MavenExecutionRequest setGlobalToolchainsFile( File globalToolchainsFile )
+    {
+        this.globalToolchainsFile = globalToolchainsFile;
+        return this;
+    }
 
     public MavenExecutionRequest addRemoteRepository( ArtifactRepository repository )
     {

http://git-wip-us.apache.org/repos/asf/maven/blob/ceae9226/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java b/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java
index 3c99d31..7daac89 100644
--- a/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java
+++ b/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java
@@ -348,6 +348,22 @@ public interface MavenExecutionRequest
 
     MavenExecutionRequest setUserToolchainsFile( File userToolchainsFile );
 
+    /**
+     * 
+     * 
+     * @return the global toolchains file
+     * @since 3.2.6
+     */
+    File getGlobalToolchainsFile();
+
+    /**
+     * 
+     * @param globalToolchainsFile the global toolchains file
+     * @return this request
+     * @since 3.2.6
+     */
+    MavenExecutionRequest setGlobalToolchainsFile( File globalToolchainsFile );
+
     ExecutionListener getExecutionListener();
 
     MavenExecutionRequest setExecutionListener( ExecutionListener executionListener );

http://git-wip-us.apache.org/repos/asf/maven/blob/ceae9226/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivate.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivate.java b/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivate.java
index 1668a80..923db00 100644
--- a/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivate.java
+++ b/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivate.java
@@ -19,11 +19,16 @@ package org.apache.maven.toolchain;
  * under the License.
  */
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.maven.building.FileSource;
 import org.apache.maven.execution.MavenSession;
+import org.apache.maven.toolchain.building.DefaultToolchainsBuildingRequest;
+import org.apache.maven.toolchain.building.ToolchainsBuildingException;
+import org.apache.maven.toolchain.building.ToolchainsBuildingResult;
 import org.apache.maven.toolchain.model.PersistedToolchains;
 import org.apache.maven.toolchain.model.ToolchainModel;
 import org.codehaus.plexus.component.annotations.Component;
@@ -31,6 +36,7 @@ import org.codehaus.plexus.component.annotations.Requirement;
 
 /**
  * @author mkleint
+ * @author Robert Scholte
  */
 @Component( role = ToolchainManagerPrivate.class )
 public class DefaultToolchainManagerPrivate
@@ -39,12 +45,36 @@ public class DefaultToolchainManagerPrivate
 {
 
     @Requirement
-    private ToolchainsBuilder toolchainsBuilder;
+    private org.apache.maven.toolchain.building.ToolchainsBuilder toolchainsBuilder;
 
     public ToolchainPrivate[] getToolchainsForType( String type, MavenSession context )
         throws MisconfiguredToolchainException
     {
-        PersistedToolchains pers = toolchainsBuilder.build( context.getRequest().getUserToolchainsFile() );
+        DefaultToolchainsBuildingRequest buildRequest = new DefaultToolchainsBuildingRequest();
+        
+        File globalToolchainsFile = context.getRequest().getGlobalToolchainsFile();
+        if ( globalToolchainsFile != null && globalToolchainsFile.isFile() )
+        {
+            buildRequest.setGlobalToolchainsSource( new FileSource( globalToolchainsFile ) );
+        }
+
+        File userToolchainsFile = context.getRequest().getUserToolchainsFile();
+        if ( userToolchainsFile != null && userToolchainsFile.isFile() )
+        {
+            buildRequest.setUserToolchainsSource( new FileSource( userToolchainsFile ) );
+        }
+        
+        ToolchainsBuildingResult buildResult;
+        try
+        {
+            buildResult = toolchainsBuilder.build( buildRequest );
+        }
+        catch ( ToolchainsBuildingException e )
+        {
+            throw new MisconfiguredToolchainException( e.getMessage(), e );
+        }
+        
+        PersistedToolchains pers = buildResult.getEffectiveToolchains();
 
         List<ToolchainPrivate> toRet = new ArrayList<ToolchainPrivate>();
 

http://git-wip-us.apache.org/repos/asf/maven/blob/ceae9226/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainsBuilder.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainsBuilder.java b/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainsBuilder.java
index 4e6e24a..5bd3e82 100644
--- a/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainsBuilder.java
+++ b/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainsBuilder.java
@@ -32,7 +32,10 @@ import org.codehaus.plexus.util.ReaderFactory;
 
 /**
  * @author Benjamin Bentmann
+ * 
+ * @deprecated instead use {@link org.apache.maven.toolchain.building.DefaultToolchainsBuilder}
  */
+@Deprecated
 @Component( role = ToolchainsBuilder.class, hint = "default" )
 public class DefaultToolchainsBuilder
     implements ToolchainsBuilder

http://git-wip-us.apache.org/repos/asf/maven/blob/ceae9226/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilder.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilder.java b/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilder.java
new file mode 100644
index 0000000..ad3363c
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilder.java
@@ -0,0 +1,136 @@
+package org.apache.maven.toolchain.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.maven.building.Problem;
+import org.apache.maven.building.ProblemCollector;
+import org.apache.maven.building.ProblemCollectorFactory;
+import org.apache.maven.building.Source;
+import org.apache.maven.toolchain.building.io.ToolchainsParseException;
+import org.apache.maven.toolchain.building.io.ToolchainsReader;
+import org.apache.maven.toolchain.merge.MavenToolchainMerger;
+import org.apache.maven.toolchain.model.PersistedToolchains;
+import org.apache.maven.toolchain.model.TrackableBase;
+
+/**
+ * 
+ * @author Robert Scholte
+ * @since 3.2.6
+ */
+@Named
+public class DefaultToolchainsBuilder
+    implements ToolchainsBuilder
+{
+    private MavenToolchainMerger toolchainsMerger = new MavenToolchainMerger();
+    
+    @Inject
+    private ToolchainsReader toolchainsReader;
+
+    @Override
+    public ToolchainsBuildingResult build( ToolchainsBuildingRequest request )
+        throws ToolchainsBuildingException
+    {
+        ProblemCollector problems = ProblemCollectorFactory.newInstance( null );
+        
+        PersistedToolchains globalToolchains = readToolchains( request.getGlobalToolchainsSource() , request, problems );
+
+        PersistedToolchains userToolchains = readToolchains( request.getUserToolchainsSource(), request, problems );
+
+        toolchainsMerger.merge( userToolchains, globalToolchains, TrackableBase.GLOBAL_LEVEL );
+        
+        problems.setSource( "" );
+        
+        if ( hasErrors( problems.getProblems() ) )
+        {
+            throw new ToolchainsBuildingException( problems.getProblems() );
+        }
+        
+        
+        return new DefaultToolchainsBuildingResult( userToolchains, problems.getProblems() );
+    }
+
+    private PersistedToolchains readToolchains( Source toolchainsSource, ToolchainsBuildingRequest request,
+                                                ProblemCollector problems )
+    {
+        if ( toolchainsSource == null )
+        {
+            return new PersistedToolchains();
+        }
+
+        PersistedToolchains toolchains;
+
+        try
+        {
+            Map<String, ?> options = Collections.singletonMap( ToolchainsReader.IS_STRICT, Boolean.TRUE );
+
+            try
+            {
+                toolchains = toolchainsReader.read( toolchainsSource.getInputStream(), options );
+            }
+            catch ( ToolchainsParseException e )
+            {
+                options = Collections.singletonMap( ToolchainsReader.IS_STRICT, Boolean.FALSE );
+
+                toolchains = toolchainsReader.read( toolchainsSource.getInputStream(), options );
+
+                problems.add( Problem.Severity.WARNING, e.getMessage(), e.getLineNumber(), e.getColumnNumber(),
+                              e );
+            }
+        }
+        catch ( ToolchainsParseException e )
+        {
+            problems.add( Problem.Severity.FATAL, "Non-parseable toolchains " + toolchainsSource.getLocation()
+                + ": " + e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e );
+            return new PersistedToolchains();
+        }
+        catch ( IOException e )
+        {
+            problems.add( Problem.Severity.FATAL, "Non-readable toolchains " + toolchainsSource.getLocation()
+                + ": " + e.getMessage(), -1, -1, e );
+            return new PersistedToolchains();
+        }
+
+        return toolchains;
+    }
+    
+    private boolean hasErrors( List<Problem> problems )
+    {
+        if ( problems != null )
+        {
+            for ( Problem problem : problems )
+            {
+                if ( Problem.Severity.ERROR.compareTo( problem.getSeverity() ) >= 0 )
+                {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/maven/blob/ceae9226/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuildingRequest.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuildingRequest.java b/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuildingRequest.java
new file mode 100644
index 0000000..7773bb3
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuildingRequest.java
@@ -0,0 +1,63 @@
+package org.apache.maven.toolchain.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.building.Source;
+
+/**
+ * Collects toolchains that control building of effective toolchains.
+ *
+ * @author Robert Scholte
+ * @since 3.2.6
+ */
+public class DefaultToolchainsBuildingRequest
+    implements ToolchainsBuildingRequest
+{
+    private Source globalToolchainsSource;
+
+    private Source userToolchainsSource;
+    
+    @Override
+    public Source getGlobalToolchainsSource()
+    {
+        return globalToolchainsSource;
+    }
+
+    @Override
+    public ToolchainsBuildingRequest setGlobalToolchainsSource( Source globalToolchainsSource )
+    {
+        this.globalToolchainsSource = globalToolchainsSource;
+        return this;
+    }
+
+    @Override
+    public Source getUserToolchainsSource()
+    {
+        return userToolchainsSource;
+    }
+
+    @Override
+    public ToolchainsBuildingRequest setUserToolchainsSource( Source userToolchainsSource )
+    {
+        this.userToolchainsSource = userToolchainsSource;
+        return this;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven/blob/ceae9226/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuildingResult.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuildingResult.java b/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuildingResult.java
new file mode 100644
index 0000000..b50473f
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuildingResult.java
@@ -0,0 +1,59 @@
+package org.apache.maven.toolchain.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.building.Problem;
+import org.apache.maven.toolchain.model.PersistedToolchains;
+
+/**
+ * 
+ * @author Robert Scholte
+ * @since 3.2.6
+ */
+public class DefaultToolchainsBuildingResult
+    implements ToolchainsBuildingResult
+{
+
+    private PersistedToolchains effectiveToolchains;
+    
+    private List<Problem> problems;
+    
+    public DefaultToolchainsBuildingResult( PersistedToolchains effectiveToolchains, List<Problem> problems )
+    {
+        this.effectiveToolchains = effectiveToolchains;
+        this.problems = ( problems != null ) ? problems : new ArrayList<Problem>();
+    }
+
+    @Override
+    public PersistedToolchains getEffectiveToolchains()
+    {
+        return effectiveToolchains;
+    }
+    
+    @Override
+    public List<Problem> getProblems()
+    {
+        return problems;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven/blob/ceae9226/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuilder.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuilder.java b/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuilder.java
new file mode 100644
index 0000000..124bd4a
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuilder.java
@@ -0,0 +1,41 @@
+package org.apache.maven.toolchain.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Builds the effective toolchains from a user toolchains file and/or a global toolchains file.
+ *
+ * @author Robert Scholte
+ * @since 3.2.6
+ */
+public interface ToolchainsBuilder
+{
+
+    /**
+     * Builds the effective toolchains of the specified toolchains files.
+     *
+     * @param request The toolchains building request that holds the parameters, must not be {@code null}.
+     * @return The result of the toolchains building, never {@code null}.
+     * @throws ToolchainsBuildingException If the effective toolchains could not be built.
+     */
+    ToolchainsBuildingResult build( ToolchainsBuildingRequest request )
+        throws ToolchainsBuildingException;
+
+}

http://git-wip-us.apache.org/repos/asf/maven/blob/ceae9226/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingException.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingException.java b/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingException.java
new file mode 100644
index 0000000..f8108a3
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingException.java
@@ -0,0 +1,88 @@
+package org.apache.maven.toolchain.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.building.Problem;
+
+/**
+ * @author Robert Scholte
+ * @since 3.2.6
+ */
+public class ToolchainsBuildingException
+    extends Exception
+{
+
+    private final List<Problem> problems;
+
+    /**
+     * Creates a new exception with the specified problems.
+     *
+     * @param problems The problems that causes this exception, may be {@code null}.
+     */
+    public ToolchainsBuildingException( List<Problem> problems )
+    {
+        super( toMessage( problems ) );
+
+        this.problems = new ArrayList<Problem>();
+        if ( problems != null )
+        {
+            this.problems.addAll( problems );
+        }
+    }
+
+    /**
+     * Gets the problems that caused this exception.
+     *
+     * @return The problems that caused this exception, never {@code null}.
+     */
+    public List<Problem> getProblems()
+    {
+        return problems;
+    }
+
+    private static String toMessage( List<Problem> problems )
+    {
+        StringWriter buffer = new StringWriter( 1024 );
+
+        PrintWriter writer = new PrintWriter( buffer );
+
+        writer.print( problems.size() );
+        writer.print( ( problems.size() == 1 ) ? " problem was " : " problems were " );
+        writer.print( "encountered while building the effective toolchains" );
+        writer.println();
+
+        for ( Problem problem : problems )
+        {
+            writer.print( "[" );
+            writer.print( problem.getSeverity() );
+            writer.print( "] " );
+            writer.print( problem.getMessage() );
+            writer.print( " @ " );
+            writer.println( problem.getLocation() );
+        }
+
+        return buffer.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/maven/blob/ceae9226/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingRequest.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingRequest.java b/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingRequest.java
new file mode 100644
index 0000000..8defdcf
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingRequest.java
@@ -0,0 +1,64 @@
+package org.apache.maven.toolchain.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.building.Source;
+
+/**
+ * Collects toolchains that control the building of effective toolchains.
+ *
+ * @author Robert Scholte
+ * @since 3.2.6
+ */
+public interface ToolchainsBuildingRequest
+{
+
+    /**
+     * Gets the global toolchains source.
+     *
+     * @return The global toolchains source or {@code null} if none.
+     */
+    Source getGlobalToolchainsSource();
+
+    /**
+     * Sets the global toolchains source. If both user toolchains and a global toolchains are given, the user toolchains take
+     * precedence.
+     *
+     * @param globalToolchainsSource The global toolchains source, may be {@code null} to disable global toolchains.
+     * @return This request, never {@code null}.
+     */
+    ToolchainsBuildingRequest setGlobalToolchainsSource( Source globalToolchainsSource );
+
+    /**
+     * Gets the user toolchains source.
+     *
+     * @return The user toolchains source or {@code null} if none.
+     */
+    Source getUserToolchainsSource();
+
+    /**
+     * Sets the user toolchains source. If both user toolchains and a global toolchains are given, the user toolchains take
+     * precedence.
+     *
+     * @param userToolchainsSource The user toolchains source, may be {@code null} to disable user toolchains.
+     * @return This request, never {@code null}.
+     */
+    ToolchainsBuildingRequest setUserToolchainsSource( Source userToolchainsSource );
+}

http://git-wip-us.apache.org/repos/asf/maven/blob/ceae9226/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingResult.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingResult.java b/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingResult.java
new file mode 100644
index 0000000..2aff1de
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingResult.java
@@ -0,0 +1,50 @@
+package org.apache.maven.toolchain.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.building.Problem;
+import org.apache.maven.toolchain.model.PersistedToolchains;
+
+/**
+ * Collects the output of the toolchains builder.
+ *
+ * @author Robert Scholte
+ * @since 3.2.6
+ */
+public interface ToolchainsBuildingResult
+{
+
+    /**
+     * Gets the assembled toolchains.
+     *
+     * @return The assembled toolchains, never {@code null}.
+     */
+    PersistedToolchains getEffectiveToolchains();
+
+    /**
+     * Return a list of problems, if any.
+     * 
+     * @return a list of problems, never {@code null}.
+     */
+    List<Problem> getProblems();
+
+}

http://git-wip-us.apache.org/repos/asf/maven/blob/ceae9226/maven-core/src/main/java/org/apache/maven/toolchain/building/io/DefaultToolchainsReader.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/toolchain/building/io/DefaultToolchainsReader.java b/maven-core/src/main/java/org/apache/maven/toolchain/building/io/DefaultToolchainsReader.java
new file mode 100644
index 0000000..616fe60
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/toolchain/building/io/DefaultToolchainsReader.java
@@ -0,0 +1,115 @@
+package org.apache.maven.toolchain.building.io;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Map;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.apache.maven.toolchain.model.PersistedToolchains;
+import org.apache.maven.toolchain.model.io.xpp3.MavenToolchainsXpp3Reader;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.ReaderFactory;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ * Handles deserialization of toolchains from the default textual format.
+ *
+ * @author Robert Scholte
+ * @since 3.2.6
+ */
+@Named
+@Singleton
+public class DefaultToolchainsReader
+    implements ToolchainsReader
+{
+
+    @Override
+    public PersistedToolchains read( File input, Map<String, ?> options )
+        throws IOException
+    {
+        if ( input == null )
+        {
+            throw new IllegalArgumentException( "input file missing" );
+        }
+
+        return read( ReaderFactory.newXmlReader( input ), options );
+    }
+
+    @Override
+    public PersistedToolchains read( Reader input, Map<String, ?> options )
+        throws IOException
+    {
+        if ( input == null )
+        {
+            throw new IllegalArgumentException( "input reader missing" );
+        }
+
+        try
+        {
+            MavenToolchainsXpp3Reader r = new MavenToolchainsXpp3Reader();
+            return r.read( input, isStrict( options ) );
+        }
+        catch ( XmlPullParserException e )
+        {
+            throw new ToolchainsParseException( e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e );
+        }
+        finally
+        {
+            IOUtil.close( input );
+        }
+    }
+
+    @Override
+    public PersistedToolchains read( InputStream input, Map<String, ?> options )
+        throws IOException
+    {
+        if ( input == null )
+        {
+            throw new IllegalArgumentException( "input stream missing" );
+        }
+
+        try
+        {
+            MavenToolchainsXpp3Reader r = new MavenToolchainsXpp3Reader();
+            return r.read( input, isStrict( options ) );
+        }
+        catch ( XmlPullParserException e )
+        {
+            throw new ToolchainsParseException( e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e );
+        }
+        finally
+        {
+            IOUtil.close( input );
+        }
+    }
+
+    private boolean isStrict( Map<String, ?> options )
+    {
+        Object value = ( options != null ) ? options.get( IS_STRICT ) : null;
+        return value == null || Boolean.parseBoolean( value.toString() );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven/blob/ceae9226/maven-core/src/main/java/org/apache/maven/toolchain/building/io/ToolchainsParseException.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/toolchain/building/io/ToolchainsParseException.java b/maven-core/src/main/java/org/apache/maven/toolchain/building/io/ToolchainsParseException.java
new file mode 100644
index 0000000..b35b3c7
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/toolchain/building/io/ToolchainsParseException.java
@@ -0,0 +1,94 @@
+package org.apache.maven.toolchain.building.io;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+
+/**
+ * Signals a failure to parse the toolchains due to invalid syntax (e.g. non-wellformed XML or unknown elements).
+ *
+ * @author Robert Scholte
+ * @since 3.2.6
+ */
+public class ToolchainsParseException
+    extends IOException
+{
+
+    /**
+     * The one-based index of the line containing the error.
+     */
+    private final int lineNumber;
+
+    /**
+     * The one-based index of the column containing the error.
+     */
+    private final int columnNumber;
+
+    /**
+     * Creates a new parser exception with the specified details.
+     *
+     * @param message The error message, may be {@code null}.
+     * @param lineNumber The one-based index of the line containing the error or {@code -1} if unknown.
+     * @param columnNumber The one-based index of the column containing the error or {@code -1} if unknown.
+     */
+    public ToolchainsParseException( String message, int lineNumber, int columnNumber )
+    {
+        super( message );
+        this.lineNumber = lineNumber;
+        this.columnNumber = columnNumber;
+    }
+
+    /**
+     * Creates a new parser exception with the specified details.
+     *
+     * @param message The error message, may be {@code null}.
+     * @param lineNumber The one-based index of the line containing the error or {@code -1} if unknown.
+     * @param columnNumber The one-based index of the column containing the error or {@code -1} if unknown.
+     * @param cause The nested cause of this error, may be {@code null}.
+     */
+    public ToolchainsParseException( String message, int lineNumber, int columnNumber, Throwable cause )
+    {
+        super( message );
+        initCause( cause );
+        this.lineNumber = lineNumber;
+        this.columnNumber = columnNumber;
+    }
+
+    /**
+     * Gets the one-based index of the line containing the error.
+     *
+     * @return The one-based index of the line containing the error or a non-positive value if unknown.
+     */
+    public int getLineNumber()
+    {
+        return lineNumber;
+    }
+
+    /**
+     * Gets the one-based index of the column containing the error.
+     *
+     * @return The one-based index of the column containing the error or non-positive value if unknown.
+     */
+    public int getColumnNumber()
+    {
+        return columnNumber;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven/blob/ceae9226/maven-core/src/main/java/org/apache/maven/toolchain/building/io/ToolchainsReader.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/toolchain/building/io/ToolchainsReader.java b/maven-core/src/main/java/org/apache/maven/toolchain/building/io/ToolchainsReader.java
new file mode 100644
index 0000000..850fdd3
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/toolchain/building/io/ToolchainsReader.java
@@ -0,0 +1,83 @@
+package org.apache.maven.toolchain.building.io;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Map;
+
+import org.apache.maven.toolchain.model.PersistedToolchains;
+
+/**
+ * Handles deserialization of toolchains from some kind of textual format like XML.
+ *
+ * @author Robert Scholte
+ * @since 3.2.6
+ */
+public interface ToolchainsReader
+{
+
+    /**
+     * The key for the option to enable strict parsing. This option is of type {@link Boolean} and defaults to {@code
+     * true}. If {@code false}, unknown elements will be ignored instead of causing a failure.
+     */
+    String IS_STRICT = "org.apache.maven.toolchains.io.isStrict";
+
+    /**
+     * Reads the toolchains from the specified file.
+     *
+     * @param input The file to deserialize the toolchains from, must not be {@code null}.
+     * @param options The options to use for deserialization, may be {@code null} to use the default values.
+     * @return The deserialized toolchains, never {@code null}.
+     * @throws IOException If the toolchains could not be deserialized.
+     * @throws ToolchainsParseException If the input format could not be parsed.
+     */
+    PersistedToolchains read( File input, Map<String, ?> options )
+        throws IOException, ToolchainsParseException;
+
+    /**
+     * Reads the toolchains from the specified character reader. The reader will be automatically closed before the method
+     * returns.
+     *
+     * @param input The reader to deserialize the toolchains from, must not be {@code null}.
+     * @param options The options to use for deserialization, may be {@code null} to use the default values.
+     * @return The deserialized toolchains, never {@code null}.
+     * @throws IOException If the toolchains could not be deserialized.
+     * @throws ToolchainsParseException If the input format could not be parsed.
+     */
+    PersistedToolchains read( Reader input, Map<String, ?> options )
+        throws IOException, ToolchainsParseException;
+
+    /**
+     * Reads the toolchains from the specified byte stream. The stream will be automatically closed before the method
+     * returns.
+     *
+     * @param input The stream to deserialize the toolchains from, must not be {@code null}.
+     * @param options The options to use for deserialization, may be {@code null} to use the default values.
+     * @return The deserialized toolchains, never {@code null}.
+     * @throws IOException If the toolchains could not be deserialized.
+     * @throws ToolchainsParseException If the input format could not be parsed.
+     */
+    PersistedToolchains read( InputStream input, Map<String, ?> options )
+        throws IOException, ToolchainsParseException;
+
+}

http://git-wip-us.apache.org/repos/asf/maven/blob/ceae9226/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java
----------------------------------------------------------------------
diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java b/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java
index 04e31b3..a78e11d 100644
--- a/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java
+++ b/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java
@@ -75,6 +75,8 @@ public class CLIManager
 
     public static final char ALTERNATE_USER_TOOLCHAINS = 't';
 
+    public static final String ALTERNATE_GLOBAL_TOOLCHAINS = "gt";
+
     public static final String FAIL_FAST = "ff";
 
     public static final String FAIL_AT_END = "fae";
@@ -125,6 +127,7 @@ public class CLIManager
         options.addOption( OptionBuilder.withLongOpt( "settings" ).withDescription( "Alternate path for the user settings file" ).hasArg().create( ALTERNATE_USER_SETTINGS ) );
         options.addOption( OptionBuilder.withLongOpt( "global-settings" ).withDescription( "Alternate path for the global settings file" ).hasArg().create( ALTERNATE_GLOBAL_SETTINGS ) );
         options.addOption( OptionBuilder.withLongOpt( "toolchains" ).withDescription( "Alternate path for the user toolchains file" ).hasArg().create( ALTERNATE_USER_TOOLCHAINS ) );
+        options.addOption( OptionBuilder.withLongOpt( "global-toolchains" ).withDescription( "Alternate path for the global toolchains file" ).hasArg().create( ALTERNATE_GLOBAL_TOOLCHAINS ) );
         options.addOption( OptionBuilder.withLongOpt( "fail-fast" ).withDescription( "Stop at first failure in reactorized builds" ).create( FAIL_FAST ) );
         options.addOption( OptionBuilder.withLongOpt( "fail-at-end" ).withDescription( "Only fail the build afterwards; allow all non-impacted builds to continue" ).create( FAIL_AT_END ) );
         options.addOption( OptionBuilder.withLongOpt( "fail-never" ).withDescription( "NEVER fail the build, regardless of project result" ).create( FAIL_NEVER ) );

http://git-wip-us.apache.org/repos/asf/maven/blob/ceae9226/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
----------------------------------------------------------------------
diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
index ef81408..c7b0485 100644
--- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
+++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
@@ -37,6 +37,7 @@ import org.apache.commons.cli.UnrecognizedOptionException;
 import org.apache.maven.BuildAbort;
 import org.apache.maven.InternalErrorException;
 import org.apache.maven.Maven;
+import org.apache.maven.building.Source;
 import org.apache.maven.cli.event.DefaultEventSpyContext;
 import org.apache.maven.cli.event.ExecutionEventLogger;
 import org.apache.maven.cli.logging.Slf4jConfiguration;
@@ -65,7 +66,7 @@ import org.apache.maven.settings.building.SettingsBuilder;
 import org.apache.maven.settings.building.SettingsBuildingRequest;
 import org.apache.maven.settings.building.SettingsBuildingResult;
 import org.apache.maven.settings.building.SettingsProblem;
-import org.apache.maven.settings.building.SettingsSource;
+import org.apache.maven.toolchain.building.ToolchainsBuilder;
 import org.codehaus.plexus.ContainerConfiguration;
 import org.codehaus.plexus.DefaultContainerConfiguration;
 import org.codehaus.plexus.DefaultPlexusContainer;
@@ -113,6 +114,9 @@ public class MavenCli
 
     public static final File DEFAULT_USER_TOOLCHAINS_FILE = new File( userMavenConfigurationHome, "toolchains.xml" );
 
+    public static final File DEFAULT_GLOBAL_TOOLCHAINS_FILE = 
+       new File( System.getProperty( "maven.home", System.getProperty( "user.dir", "" ) ), "conf/toolchains.xml" );
+
     private static final String EXT_CLASS_PATH = "maven.ext.class.path";
 
     private ClassWorld classWorld;
@@ -133,6 +137,8 @@ public class MavenCli
 
     private SettingsBuilder settingsBuilder;
 
+    private ToolchainsBuilder toolchainsBuilder;
+
     private DefaultSecDispatcher dispatcher;
 
     public MavenCli()
@@ -210,6 +216,7 @@ public class MavenCli
             localContainer = container( cliRequest );
             commands( cliRequest );
             settings( cliRequest );
+            toolchains( cliRequest );
             populateRequest( cliRequest );
             encryption( cliRequest );
             repository( cliRequest );
@@ -761,10 +768,10 @@ public class MavenCli
         eventSpyDispatcher.onEvent( settingsRequest );
 
         slf4jLogger.debug( "Reading global settings from "
-            + getSettingsLocation( settingsRequest.getGlobalSettingsSource(),
+            + getLocation( settingsRequest.getGlobalSettingsSource(),
                                    settingsRequest.getGlobalSettingsFile() ) );
         slf4jLogger.debug( "Reading user settings from "
-            + getSettingsLocation( settingsRequest.getUserSettingsSource(), settingsRequest.getUserSettingsFile() ) );
+            + getLocation( settingsRequest.getUserSettingsSource(), settingsRequest.getUserSettingsFile() ) );
 
         SettingsBuildingResult settingsResult = settingsBuilder.build( settingsRequest );
 
@@ -785,8 +792,57 @@ public class MavenCli
             slf4jLogger.warn( "" );
         }
     }
+    
+    @SuppressWarnings( "checkstyle:methodlength" )
+    private void toolchains( CliRequest cliRequest )
+        throws Exception
+    {
+        File userToolchainsFile;
+
+        if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_USER_TOOLCHAINS ) )
+        {
+            userToolchainsFile =
+                new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_USER_TOOLCHAINS ) );
+            userToolchainsFile = resolveFile( userToolchainsFile, cliRequest.workingDirectory );
+
+            if ( !userToolchainsFile.isFile() )
+            {
+                throw new FileNotFoundException( "The specified user toolchains file does not exist: "
+                    + userToolchainsFile );
+            }
+        }
+        else
+        {
+            userToolchainsFile = DEFAULT_USER_TOOLCHAINS_FILE;
+        }
+
+        File globalToolchainsFile;
+
+        if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_GLOBAL_TOOLCHAINS ) )
+        {
+            globalToolchainsFile =
+                new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_GLOBAL_TOOLCHAINS ) );
+            globalToolchainsFile = resolveFile( globalToolchainsFile, cliRequest.workingDirectory );
+
+            if ( !globalToolchainsFile.isFile() )
+            {
+                throw new FileNotFoundException( "The specified global toolchains file does not exist: "
+                    + globalToolchainsFile );
+            }
+        }
+        else
+        {
+            globalToolchainsFile = DEFAULT_GLOBAL_TOOLCHAINS_FILE;
+        }
+
+        cliRequest.request.setGlobalToolchainsFile( globalToolchainsFile );
+        cliRequest.request.setUserToolchainsFile( userToolchainsFile );
+        
+        // Unlike settings, the toolchains aren't built here. 
+        // That's done by the maven-toolchains-plugin, by calling it from the project with the proper configuration
+    }
 
-    private Object getSettingsLocation( SettingsSource source, File file )
+    private Object getLocation( Source source, File file )
     {
         if ( source != null )
         {
@@ -974,7 +1030,7 @@ public class MavenCli
             .setUpdateSnapshots( updateSnapshots ) // default: false
             .setNoSnapshotUpdates( noSnapshotUpdates ) // default: false
             .setGlobalChecksumPolicy( globalChecksumPolicy ) // default: warn
-            .setUserToolchainsFile( userToolchainsFile );
+            ;
 
         if ( alternatePomFile != null )
         {