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:50 UTC

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

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 ) ) );
+    }
 
 }