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 2019/01/11 08:27:49 UTC

[maven-invoker-plugin] branch MINVOKER-245 created (now 7c70e76)

This is an automated email from the ASF dual-hosted git repository.

rfscholte pushed a change to branch MINVOKER-245
in repository https://gitbox.apache.org/repos/asf/maven-invoker-plugin.git.


      at 7c70e76  [MINVOKER-245] Using an alternate toolchain file Add toolchain selector

This branch includes the following new commits:

     new 7c70e76  [MINVOKER-245] Using an alternate toolchain file Add toolchain selector

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[maven-invoker-plugin] 01/01: [MINVOKER-245] Using an alternate toolchain file Add toolchain selector

Posted by rf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rfscholte pushed a commit to branch MINVOKER-245
in repository https://gitbox.apache.org/repos/asf/maven-invoker-plugin.git

commit 7c70e76c4fc7e1cf6e2eeb460deb39a1b10b4def
Author: rfscholte <rf...@apache.org>
AuthorDate: Fri Jan 11 09:27:40 2019 +0100

    [MINVOKER-245] Using an alternate toolchain file
    Add toolchain selector
---
 pom.xml                                            |  6 +++
 .../src/it/toolchain-mismatch/invoker.properties   | 18 +++++++
 .../src/it/toolchain-mismatch/pom.xml              | 32 +++++++++++
 .../it/toolchain-mismatch/postbuild.bsh}           | 15 +++---
 src/it/selector-conditions/verify.bsh              | 62 ----------------------
 src/it/selector-conditions/verify.groovy           | 38 +++++++++++++
 .../maven/plugins/invoker/AbstractInvokerMojo.java | 50 ++++++++++++++++-
 .../maven/plugins/invoker/InvokerProperties.java   | 40 +++++++++++++-
 .../maven/plugins/invoker/InvokerToolchain.java}   | 50 ++++++++++++-----
 .../org/apache/maven/plugins/invoker/Selector.java | 22 +++++++-
 .../maven/plugins/invoker/SelectorUtils.java       | 44 +++++++++++++++
 .../apache/maven/plugins/invoker/SelectorTest.java |  6 +--
 .../maven/plugins/invoker/SelectorUtilsTest.java   | 55 +++++++++++++++++--
 13 files changed, 343 insertions(+), 95 deletions(-)

diff --git a/pom.xml b/pom.xml
index da83e0c..91b9956 100644
--- a/pom.xml
+++ b/pom.xml
@@ -226,6 +226,12 @@ under the License.
       <scope>test</scope>
     </dependency>
     <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <version>2.23.4</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.apache.maven.plugin-testing</groupId>
       <artifactId>maven-plugin-testing-harness</artifactId>
       <version>2.1</version>
diff --git a/src/it/selector-conditions/src/it/toolchain-mismatch/invoker.properties b/src/it/selector-conditions/src/it/toolchain-mismatch/invoker.properties
new file mode 100644
index 0000000..b22a425
--- /dev/null
+++ b/src/it/selector-conditions/src/it/toolchain-mismatch/invoker.properties
@@ -0,0 +1,18 @@
+# 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.
+
+invoker.toolchain.jdk.vendor = mycomp
diff --git a/src/it/selector-conditions/src/it/toolchain-mismatch/pom.xml b/src/it/selector-conditions/src/it/toolchain-mismatch/pom.xml
new file mode 100644
index 0000000..ea5c00f
--- /dev/null
+++ b/src/it/selector-conditions/src/it/toolchain-mismatch/pom.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>test</groupId>
+  <artifactId>test</artifactId>
+  <version>0.1-SNAPSHOT</version>
+  <packaging>pom</packaging>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+</project>
diff --git a/src/it/selector-conditions/setup.groovy b/src/it/selector-conditions/src/it/toolchain-mismatch/postbuild.bsh
similarity index 61%
copy from src/it/selector-conditions/setup.groovy
copy to src/it/selector-conditions/src/it/toolchain-mismatch/postbuild.bsh
index db885b6..d2e394e 100644
--- a/src/it/selector-conditions/setup.groovy
+++ b/src/it/selector-conditions/src/it/toolchain-mismatch/postbuild.bsh
@@ -17,13 +17,10 @@
  * under the License.
  */
 
-import java.io.File
-import org.apache.commons.io.FileUtils
+import java.io.*;
 
-// Previous potential target 'content' has impact on IT execution
-// (Some new file should be created by verify.sh) 
-FileUtils.deleteQuietly( new File( basedir, "target/invoker-reports" ) );
-FileUtils.deleteQuietly( new File( basedir, "src/it/jre-version-match/target" ) );
-FileUtils.deleteQuietly( new File( basedir, "src/it/maven-version-match/target" ) );
-FileUtils.deleteQuietly( new File( basedir, "src/it/os-family-match/target" ) );
-return true;
+// create touch file so that the parent build can verify whether this build was executed
+File touchFile = new File( basedir, "target/touch.txt" );
+System.out.println( "Creating touch file: " + touchFile );
+touchFile.getParentFile().mkdirs();
+touchFile.createNewFile();
diff --git a/src/it/selector-conditions/verify.bsh b/src/it/selector-conditions/verify.bsh
deleted file mode 100644
index 2618914..0000000
--- a/src/it/selector-conditions/verify.bsh
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.*;
-import java.util.*;
-import java.util.regex.*;
-
-try
-{
-    String[] expected = {
-            "target/its/jre-version-match/target/touch.txt",
-            "target/its/os-family-match/target/touch.txt",
-      };
-    for ( String file : expected )
-    {
-        File touchFile = new File( basedir, file );
-        System.out.println( "Checking for existence of: " + touchFile );
-        if ( !touchFile.isFile() )
-        {
-            System.out.println( "FAILED!" );
-            return false;
-        }
-    }
-
-    String[] unexpected = {
-            "target/its/jre-version-mismatch/target/touch.txt",
-            "target/its/os-family-mismatch/target/touch.txt",
-      };
-    for ( String file : unexpected )
-    {
-        File touchFile = new File( basedir, file );
-        System.out.println( "Checking for absence of: " + touchFile );
-        if ( touchFile.exists() )
-        {
-            System.out.println( "FAILED!" );
-            return false;
-        }
-    }
-}
-catch( Throwable t )
-{
-    t.printStackTrace();
-    return false;
-}
-
-return true;
diff --git a/src/it/selector-conditions/verify.groovy b/src/it/selector-conditions/verify.groovy
new file mode 100644
index 0000000..68eb51e
--- /dev/null
+++ b/src/it/selector-conditions/verify.groovy
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+def FS = System.getProperty('file.separator')
+
+assert new File(basedir, 'target/its/jre-version-match/build.log').exists()
+assert !(new File(basedir, 'target/its/jre-version-mismatch/build.log').exists())
+assert new File(basedir, 'target/its/maven-version-match/build.log').exists()
+assert !(new File(basedir, 'target/its/maven-version-mismatch/build.log').exists())
+assert new File(basedir, 'target/its/os-family-match/build.log').exists()
+assert !(new File(basedir, 'target/its/os-family-mismatch/build.log').exists())
+assert !(new File(basedir, 'target/its/toolchain-mismatch/build.log').exists())
+
+def log = new File( basedir, 'build.log').text
+
+assert log.contains("jre-version-match${FS}pom.xml ........................ SUCCESS")
+assert log.contains("jre-version-mismatch${FS}pom.xml ..................... SKIPPED due to JRE version")
+assert log.contains("maven-version-match${FS}pom.xml ...................... SUCCESS")
+assert log.contains("maven-version-mismatch${FS}pom.xml ................... SKIPPED due to Maven version")
+assert log.contains("os-family-match${FS}pom.xml .......................... SUCCESS")
+assert log.contains("os-family-mismatch${FS}pom.xml ....................... SKIPPED due to OS")
+assert log.contains("toolchain-mismatch${FS}pom.xml ....................... SKIPPED due to Toolchain")
\ No newline at end of file
diff --git a/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java b/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java
index e75c2c4..13ab1a8 100644
--- a/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java
+++ b/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java
@@ -20,6 +20,7 @@ package org.apache.maven.plugins.invoker;
  */
 
 import org.apache.maven.artifact.Artifact;
+import org.apache.maven.execution.MavenSession;
 import org.apache.maven.model.Model;
 import org.apache.maven.model.Profile;
 import org.apache.maven.plugin.AbstractMojo;
@@ -50,6 +51,9 @@ import org.apache.maven.shared.scriptinterpreter.RunErrorException;
 import org.apache.maven.shared.scriptinterpreter.RunFailureException;
 import org.apache.maven.shared.scriptinterpreter.ScriptRunner;
 import org.apache.maven.shared.utils.logging.MessageBuilder;
+import org.apache.maven.toolchain.MisconfiguredToolchainException;
+import org.apache.maven.toolchain.ToolchainManagerPrivate;
+import org.apache.maven.toolchain.ToolchainPrivate;
 import org.codehaus.plexus.interpolation.InterpolationException;
 import org.codehaus.plexus.interpolation.Interpolator;
 import org.codehaus.plexus.interpolation.MapBasedValueSource;
@@ -255,6 +259,9 @@ public abstract class AbstractInvokerMojo
 
     @Component
     private SettingsBuilder settingsBuilder;
+    
+    @Component
+    private ToolchainManagerPrivate toolchainManagerPrivate;
 
     /**
      * Relative path of a selector script to run prior in order to decide if the build should be executed. This script
@@ -348,6 +355,9 @@ public abstract class AbstractInvokerMojo
     @Parameter( defaultValue = "${project}", readonly = true, required = true )
     private MavenProject project;
 
+    @Parameter( defaultValue = "${session}", readonly = true, required = true )
+    private MavenSession session;
+
     @Parameter( defaultValue = "${mojoExecution}", readonly = true, required = true )
     private MojoExecution mojoExecution;
 
@@ -514,7 +524,12 @@ public abstract class AbstractInvokerMojo
      * # Since plugin version 1.5
      * invoker.maven.version = 2.0.10+, !2.1.0, !2.2.0
      * 
-     * # For java.version, maven.version and os.family it is possible to define multiple selectors.
+     * # A mapping for toolchain to ensure it exists
+     * # Since plugin version 3.2.0
+     * invoker.toolchain.&lt;type&gt;.&lt;provides&gt; = value
+     * invoker.toolchain.jdk.version = 11
+     * 
+     * # For java.version, maven.version, os.family and toolchain it is possible to define multiple selectors.
      * # If one of the indexed selectors matches, the test is executed.
      * # With the invoker.x.y equivalents you can specify global matchers.  
      * selector.1.java.version = 1.8+
@@ -1584,6 +1599,14 @@ public abstract class AbstractInvokerMojo
                         }
                         message.append( "OS" );
                     }
+                    if ( ( selection & Selector.SELECTOR_TOOLCHAIN ) != 0 )
+                    {
+                        if ( message.length() > 0 )
+                        {
+                            message.append( ", " );
+                        }
+                        message.append( "Toolchain" );
+                    }
                 }
 
                 if ( !suppressSummaries )
@@ -1673,7 +1696,13 @@ public abstract class AbstractInvokerMojo
      */
     private int getSelection( InvokerProperties invokerProperties, CharSequence actualJreVersion )
     {
-        return new Selector( actualMavenVersion, actualJreVersion.toString() ).getSelection( invokerProperties );
+        return new Selector( actualMavenVersion, actualJreVersion.toString(),
+                             getToolchainPrivateManager() ).getSelection( invokerProperties );
+    }
+
+    private ToolchainPrivateManager getToolchainPrivateManager()
+    {
+        return new ToolchainPrivateManager( toolchainManagerPrivate, session );
     }
 
     /**
@@ -2561,4 +2590,21 @@ public abstract class AbstractInvokerMojo
         return parallelThreads > 1;
     }
 
+    static class ToolchainPrivateManager
+    {
+        private ToolchainManagerPrivate manager;
+        
+        private MavenSession session;
+
+        ToolchainPrivateManager( ToolchainManagerPrivate manager, MavenSession session )
+        {
+            this.manager = manager;
+            this.session = session;
+        }
+
+        ToolchainPrivate[] getToolchainPrivates( String type ) throws MisconfiguredToolchainException
+        {
+            return manager.getToolchainsForType( type, session );
+        }
+    }
 }
diff --git a/src/main/java/org/apache/maven/plugins/invoker/InvokerProperties.java b/src/main/java/org/apache/maven/plugins/invoker/InvokerProperties.java
index 0e0124f..e8ba20e 100644
--- a/src/main/java/org/apache/maven/plugins/invoker/InvokerProperties.java
+++ b/src/main/java/org/apache/maven/plugins/invoker/InvokerProperties.java
@@ -22,7 +22,12 @@ package org.apache.maven.plugins.invoker;
 import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Properties;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.apache.maven.shared.invoker.InvocationRequest;
 import org.apache.maven.shared.invoker.InvocationRequest.ReactorFailureBehavior;
@@ -196,8 +201,41 @@ class InvokerProperties
     {
         return this.properties.getProperty( SELECTOR_PREFIX + index + SelectorProperty.OS_FAMLY.suffix,
                                             getOsFamily() );
-    }   
+    }
     
+    public Collection<InvokerToolchain> getToolchains()
+    {
+        return getToolchains( Pattern.compile( "invoker\\.toolchain\\.([^\\.]+)\\.(.+)" ) );
+    }
+
+    public Collection<InvokerToolchain> getToolchains( int index )
+    {
+        return getToolchains( Pattern.compile( "selector\\." + index + "\\.invoker\\.toolchain\\.([^\\.]+)\\.(.+)" ) );
+    }
+
+    private Collection<InvokerToolchain> getToolchains( Pattern p )
+    {
+        Map<String, InvokerToolchain> toolchains = new HashMap<>();
+        for ( Map.Entry<Object, Object> entry : this.properties.entrySet() )
+        {
+            Matcher m = p.matcher( entry.getKey().toString() );
+            if ( m.matches() )
+            {
+                String type = m.group( 1 );
+                String providesKey = m.group( 2 );
+                String providesValue = entry.getValue().toString();
+
+                InvokerToolchain tc = toolchains.get( type );
+                if ( tc == null )
+                {
+                    tc = new InvokerToolchain( type );
+                    toolchains.put( type, tc );
+                }
+                tc.addProvides( providesKey, providesValue );
+            }
+        }
+        return toolchains.values();
+    }
 
     /**
      * Determines whether these invoker properties contain a build definition for the specified invocation index.
diff --git a/src/it/selector-conditions/setup.groovy b/src/main/java/org/apache/maven/plugins/invoker/InvokerToolchain.java
similarity index 53%
rename from src/it/selector-conditions/setup.groovy
rename to src/main/java/org/apache/maven/plugins/invoker/InvokerToolchain.java
index db885b6..c2381fe 100644
--- a/src/it/selector-conditions/setup.groovy
+++ b/src/main/java/org/apache/maven/plugins/invoker/InvokerToolchain.java
@@ -1,3 +1,5 @@
+package org.apache.maven.plugins.invoker;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -6,9 +8,9 @@
  * 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
- * 
+ *
+ *  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
@@ -17,13 +19,37 @@
  * under the License.
  */
 
-import java.io.File
-import org.apache.commons.io.FileUtils
+import java.util.HashMap;
+import java.util.Map;
 
-// Previous potential target 'content' has impact on IT execution
-// (Some new file should be created by verify.sh) 
-FileUtils.deleteQuietly( new File( basedir, "target/invoker-reports" ) );
-FileUtils.deleteQuietly( new File( basedir, "src/it/jre-version-match/target" ) );
-FileUtils.deleteQuietly( new File( basedir, "src/it/maven-version-match/target" ) );
-FileUtils.deleteQuietly( new File( basedir, "src/it/os-family-match/target" ) );
-return true;
+/**
+ * 
+ * @author Robert Scholte
+ * @since 3.2.0
+ */
+public class InvokerToolchain
+{
+    private final String type;
+    
+    private Map<String, String> provides = new HashMap<>();
+    
+    public InvokerToolchain( String type )
+    {
+        this.type = type;
+    }
+    
+    public String getType()
+    {
+        return type;
+    }
+    
+    public void addProvides( String key, String value )
+    {
+        provides.put( key, value );
+    }
+    
+    public Map<String, String> getProvides()
+    {
+        return provides;
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/invoker/Selector.java b/src/main/java/org/apache/maven/plugins/invoker/Selector.java
index f1386d4..0391dd3 100644
--- a/src/main/java/org/apache/maven/plugins/invoker/Selector.java
+++ b/src/main/java/org/apache/maven/plugins/invoker/Selector.java
@@ -19,6 +19,8 @@ package org.apache.maven.plugins.invoker;
  * under the License.
  */
 
+import org.apache.maven.plugins.invoker.AbstractInvokerMojo.ToolchainPrivateManager;
+
 /**
  * 
  * @author Robert Scholte
@@ -32,16 +34,21 @@ class Selector
 
     static final int SELECTOR_OSFAMILY = 4;
     
-    static final int SELECTOR_MULTI = 8;
+    static final int SELECTOR_TOOLCHAIN = 8;
+
+    static final int SELECTOR_MULTI = 16;
     
     private final String actualMavenVersion;
     
     private final String actualJavaVersion;
     
-    Selector( String actualMavenVersion, String actualJavaVersion )
+    private final ToolchainPrivateManager toolchainPrivateManager; 
+    
+    Selector( String actualMavenVersion, String actualJavaVersion, ToolchainPrivateManager toolchainPrivateManager )
     {
         this.actualMavenVersion = actualMavenVersion;
         this.actualJavaVersion = actualJavaVersion;
+        this.toolchainPrivateManager = toolchainPrivateManager;
     }
     
     public int getSelection( InvokerProperties invokerProperties ) 
@@ -75,6 +82,12 @@ class Selector
                 selection |= SELECTOR_OSFAMILY;
             }
 
+            if ( !SelectorUtils.isToolchain( toolchainPrivateManager,
+                                             invokerProperties.getToolchains( selectorIndex ) ) )
+            {
+                selection |= SELECTOR_TOOLCHAIN;
+            }
+
             if ( selection == 0 )
             {
                 return 0;
@@ -108,6 +121,11 @@ class Selector
             selection |= SELECTOR_OSFAMILY;
         }
 
+        if ( !SelectorUtils.isToolchain( toolchainPrivateManager, invokerProperties.getToolchains() ) )
+        {
+            selection |= SELECTOR_TOOLCHAIN;
+        }
+
         return selection;
     }
 }
diff --git a/src/main/java/org/apache/maven/plugins/invoker/SelectorUtils.java b/src/main/java/org/apache/maven/plugins/invoker/SelectorUtils.java
index 5f18259..fe89761 100644
--- a/src/main/java/org/apache/maven/plugins/invoker/SelectorUtils.java
+++ b/src/main/java/org/apache/maven/plugins/invoker/SelectorUtils.java
@@ -30,7 +30,10 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Properties;
 
+import org.apache.maven.plugins.invoker.AbstractInvokerMojo.ToolchainPrivateManager;
 import org.apache.maven.project.MavenProject;
+import org.apache.maven.toolchain.MisconfiguredToolchainException;
+import org.apache.maven.toolchain.ToolchainPrivate;
 import org.codehaus.plexus.util.Os;
 import org.codehaus.plexus.util.StringUtils;
 
@@ -279,5 +282,46 @@ class SelectorUtils
             }
         }
     }
+    
+    /**
+     * @param toolchainPrivateManager
+     * @param invokerToolchains
+     * @return {@code true} if all invokerToolchains are available, otherwise {@code false}
+     */
+    static boolean isToolchain( ToolchainPrivateManager toolchainPrivateManager,
+                                Collection<InvokerToolchain> invokerToolchains )
+    {
+        for ( InvokerToolchain invokerToolchain : invokerToolchains )
+        {
+            boolean found = false;
+            try
+            {
+                for ( ToolchainPrivate tc : toolchainPrivateManager.getToolchainPrivates( invokerToolchain.getType() ) )
+                {
+                    if ( !invokerToolchain.getType().equals( tc.getType() ) )
+                    {
+                        // useful because of MNG-5716
+                        continue;
+                    }
+
+                    if ( tc.matchesRequirements( invokerToolchain.getProvides() ) )
+                    {
+                        found = true;
+                        continue;
+                    }
+                }
+            }
+            catch ( MisconfiguredToolchainException e )
+            {
+                return false;
+            }
+            
+            if ( !found )
+            { 
+                return false;
+            }
+        }
 
+        return true;
+    }
 }
diff --git a/src/test/java/org/apache/maven/plugins/invoker/SelectorTest.java b/src/test/java/org/apache/maven/plugins/invoker/SelectorTest.java
index 70886fc..bd79a5a 100644
--- a/src/test/java/org/apache/maven/plugins/invoker/SelectorTest.java
+++ b/src/test/java/org/apache/maven/plugins/invoker/SelectorTest.java
@@ -31,7 +31,7 @@ public class SelectorTest
     @Test
     public void testGlobalMatch()
     {
-        Selector selector = new Selector( "3.2.5", "1.7" );
+        Selector selector = new Selector( "3.2.5", "1.7", null );
 
         Properties props = new Properties();
         props.setProperty( "invoker.maven.version", "3.0+" );
@@ -42,7 +42,7 @@ public class SelectorTest
     @Test
     public void testSelectorMatch()
     {
-        Selector selector = new Selector( "3.2.5", "1.7" );
+        Selector selector = new Selector( "3.2.5", "1.7", null );
 
         Properties props = new Properties();
         props.setProperty( "selector.1.maven.version", "3.0+" );
@@ -56,7 +56,7 @@ public class SelectorTest
     @Test
     public void testSelectorWithGlobalMatch()
     {
-        Selector selector = new Selector( "3.2.5", "1.7" );
+        Selector selector = new Selector( "3.2.5", "1.7", null );
 
         Properties props = new Properties();
         // invoker.maven.version is used by all selectors
diff --git a/src/test/java/org/apache/maven/plugins/invoker/SelectorUtilsTest.java b/src/test/java/org/apache/maven/plugins/invoker/SelectorUtilsTest.java
index 02760da..785f974 100644
--- a/src/test/java/org/apache/maven/plugins/invoker/SelectorUtilsTest.java
+++ b/src/test/java/org/apache/maven/plugins/invoker/SelectorUtilsTest.java
@@ -19,13 +19,22 @@ package org.apache.maven.plugins.invoker;
  * under the License.
  */
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.isA;
+
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
-import org.apache.maven.plugins.invoker.SelectorUtils;
-
-import junit.framework.TestCase;
+import org.apache.maven.plugins.invoker.AbstractInvokerMojo.ToolchainPrivateManager;
+import org.apache.maven.toolchain.ToolchainPrivate;
+import org.junit.Test;
 
 /**
  * Tests {@link SelectorUtils}.
@@ -33,9 +42,9 @@ import junit.framework.TestCase;
  * @author Benjamin Bentmann
  */
 public class SelectorUtilsTest
-    extends TestCase
 {
 
+    @Test
     public void testParseList()
     {
         List<String> includes = new ArrayList<String>();
@@ -48,6 +57,7 @@ public class SelectorUtilsTest
         assertEquals( Arrays.asList( "1.4" ), excludes );
     }
 
+    @Test
     public void testParseVersion()
     {
         assertEquals( Arrays.asList( 1, 6, 0, 12 ), SelectorUtils.parseVersion( "1.6.0_12" ) );
@@ -56,6 +66,7 @@ public class SelectorUtilsTest
         assertEquals( Arrays.asList( 1, 6, 0, 12 ), SelectorUtils.parseVersion( "1.6.0_12-" ) );
     }
 
+    @Test
     public void testCompareVersions()
     {
         assertTrue( SelectorUtils.compareVersions( Arrays.asList( 1, 6 ), Arrays.asList( 1, 6 ) ) == 0 );
@@ -67,6 +78,7 @@ public class SelectorUtilsTest
         assertTrue( SelectorUtils.compareVersions( Arrays.asList( 1, 6 ), Arrays.asList( 1 ) ) > 0 );
     }
 
+    @Test
     public void testIsMatchingJre()
     {
 
@@ -88,5 +100,40 @@ public class SelectorUtilsTest
         assertTrue( SelectorUtils.isJreVersion( (String) null, "1.5" ) );
         assertTrue( SelectorUtils.isJreVersion( "", "1.5" ) );
     }
+    
+    @Test
+    public void testIsMatchingToolchain() throws Exception
+    {
+        InvokerToolchain openJdk9 = new InvokerToolchain( "jdk" );
+        openJdk9.addProvides( "version", "9" );
+        openJdk9.addProvides( "vendor", "openJDK" );
+
+        InvokerToolchain maven360 = new InvokerToolchain( "maven" );
+        openJdk9.addProvides( "version", "3.6.0" );
+
+        ToolchainPrivateManager toolchainPrivateManager = mock( ToolchainPrivateManager.class );
+        ToolchainPrivate jdkMatching = mock( ToolchainPrivate.class );
+        when( jdkMatching.matchesRequirements( isA( Map.class ) ) ).thenReturn( true );
+        when( jdkMatching.getType() ).thenReturn( "jdk");
+
+        ToolchainPrivate jdkMismatch = mock( ToolchainPrivate.class );
+        when( jdkMismatch.getType() ).thenReturn( "jdk");
+
+        when( toolchainPrivateManager.getToolchainPrivates( "jdk" ) ).thenReturn( new ToolchainPrivate[] { jdkMatching } );
+        assertTrue( SelectorUtils.isToolchain( toolchainPrivateManager, Collections.singleton( openJdk9 ) ) );
+
+        when( toolchainPrivateManager.getToolchainPrivates( "jdk" ) ).thenReturn( new ToolchainPrivate[] { jdkMismatch } );
+        assertFalse( SelectorUtils.isToolchain( toolchainPrivateManager, Collections.singleton( openJdk9 ) ) );
+
+        when( toolchainPrivateManager.getToolchainPrivates( "jdk" ) ).thenReturn( new ToolchainPrivate[] { jdkMatching, jdkMismatch, jdkMatching } );
+        assertTrue( SelectorUtils.isToolchain( toolchainPrivateManager, Collections.singleton( openJdk9 ) ) );
+
+        when( toolchainPrivateManager.getToolchainPrivates( "jdk" ) ).thenReturn( new ToolchainPrivate[0] );
+        assertFalse( SelectorUtils.isToolchain( toolchainPrivateManager, Collections.singleton( openJdk9 ) ) );
+        
+        when( toolchainPrivateManager.getToolchainPrivates( "jdk" ) ).thenReturn( new ToolchainPrivate[] { jdkMatching } );
+        when( toolchainPrivateManager.getToolchainPrivates( "maven" ) ).thenReturn( new ToolchainPrivate[0] );
+        assertFalse( SelectorUtils.isToolchain( toolchainPrivateManager, Arrays.asList( openJdk9, maven360 ) ) );
+    }
 
 }