You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by sc...@apache.org on 2017/01/31 03:02:34 UTC

[35/50] maven git commit: [MNG-5993] Confusing error message in case of missing/empty artifactId/groupId and version in pluginManagement

[MNG-5993] Confusing error message in case of missing/empty
 artifactId/groupId and version in pluginManagement


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

Branch: refs/heads/MNG-5359-IT
Commit: 017dcaf22a2cc1c6361dc64a02d1bdbdb799b95e
Parents: 065281c
Author: Karl Heinz Marbaise <kh...@apache.org>
Authored: Fri Apr 1 22:53:37 2016 +0200
Committer: Karl Heinz Marbaise <kh...@apache.org>
Committed: Sun Jan 29 21:12:49 2017 +0100

----------------------------------------------------------------------
 .../internal/LifecyclePluginResolver.java       |  12 +-
 .../internal/DefaultPluginVersionResolver.java  |   6 +-
 .../model/validation/DefaultModelValidator.java | 170 +++++++++++--------
 .../validation/DefaultModelValidatorTest.java   |  73 ++++++--
 .../missing-artifactId-pluginManagement.xml     |  39 +++++
 .../raw-model/missing-ga-pluginManagement.xml   |  39 +++++
 .../missing-groupId-pluginManagement.xml        |  39 +++++
 .../missing-plugin-version-pluginManagement.xml |  40 +++++
 8 files changed, 321 insertions(+), 97 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven/blob/017dcaf2/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecyclePluginResolver.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecyclePluginResolver.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecyclePluginResolver.java
index 956e717..f02552a 100644
--- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecyclePluginResolver.java
+++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecyclePluginResolver.java
@@ -19,6 +19,9 @@ package org.apache.maven.lifecycle.internal;
  * under the License.
  */
 
+import java.util.HashMap;
+import java.util.Map;
+
 import org.apache.maven.execution.MavenSession;
 import org.apache.maven.model.Plugin;
 import org.apache.maven.model.PluginManagement;
@@ -30,9 +33,6 @@ import org.apache.maven.project.MavenProject;
 import org.codehaus.plexus.component.annotations.Component;
 import org.codehaus.plexus.component.annotations.Requirement;
 
-import java.util.HashMap;
-import java.util.Map;
-
 /**
  * @since 3.0
  * @author Benjamin Bentmann
@@ -46,7 +46,6 @@ public class LifecyclePluginResolver
     @Requirement
     private PluginVersionResolver pluginVersionResolver;
 
-
     public LifecyclePluginResolver( PluginVersionResolver pluginVersionResolver )
     {
         this.pluginVersionResolver = pluginVersionResolver;
@@ -65,9 +64,8 @@ public class LifecyclePluginResolver
         {
             if ( plugin.getVersion() == null )
             {
-                PluginVersionRequest request =
-                    new DefaultPluginVersionRequest( plugin, session.getRepositorySession(),
-                                                     project.getRemotePluginRepositories() );
+                PluginVersionRequest request = new DefaultPluginVersionRequest( plugin, session.getRepositorySession(),
+                                                                                project.getRemotePluginRepositories() );
                 plugin.setVersion( pluginVersionResolver.resolve( request ).getVersion() );
             }
             versions.put( plugin.getKey(), plugin.getVersion() );

http://git-wip-us.apache.org/repos/asf/maven/blob/017dcaf2/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResolver.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResolver.java b/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResolver.java
index f11ee95..82e32fb 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResolver.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResolver.java
@@ -87,8 +87,6 @@ public class DefaultPluginVersionResolver
     public PluginVersionResult resolve( PluginVersionRequest request )
         throws PluginVersionResolutionException
     {
-        logger.debug( "Resolving plugin version for " + request.getGroupId() + ":" + request.getArtifactId() );
-
         PluginVersionResult result = resolveFromProject( request );
 
         if ( result == null )
@@ -103,8 +101,8 @@ public class DefaultPluginVersionResolver
         }
         else if ( logger.isDebugEnabled() )
         {
-            logger.debug( "Resolved plugin version for " + request.getGroupId() + ":" + request.getArtifactId()
-                + " to " + result.getVersion() + " from POM " + request.getPom() );
+            logger.debug( "Resolved plugin version for " + request.getGroupId() + ":" + request.getArtifactId() + " to "
+                + result.getVersion() + " from POM " + request.getPom() );
         }
 
         return result;

http://git-wip-us.apache.org/repos/asf/maven/blob/017dcaf2/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java
----------------------------------------------------------------------
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java b/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java
index 1d3a0f6..cea2a74 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java
@@ -83,17 +83,18 @@ public class DefaultModelValidator
             validateStringNotEmpty( "parent.groupId", problems, Severity.FATAL, Version.BASE, parent.getGroupId(),
                                     parent );
 
-            validateStringNotEmpty( "parent.artifactId", problems, Severity.FATAL, Version.BASE,
-                                    parent.getArtifactId(), parent );
+            validateStringNotEmpty( "parent.artifactId", problems, Severity.FATAL, Version.BASE, parent.getArtifactId(),
+                                    parent );
 
             validateStringNotEmpty( "parent.version", problems, Severity.FATAL, Version.BASE, parent.getVersion(),
                                     parent );
 
-            if ( equals( parent.getGroupId(), m.getGroupId() )
-                && equals( parent.getArtifactId(), m.getArtifactId() ) )
+            if ( equals( parent.getGroupId(), m.getGroupId() ) && equals( parent.getArtifactId(), m.getArtifactId() ) )
             {
-                addViolation( problems, Severity.FATAL, Version.BASE, "parent.artifactId", null, "must be changed"
-                    + ", the parent element cannot have the same groupId:artifactId as the project.", parent );
+                addViolation( problems, Severity.FATAL, Version.BASE, "parent.artifactId", null,
+                              "must be changed"
+                                  + ", the parent element cannot have the same groupId:artifactId as the project.",
+                              parent );
             }
         }
 
@@ -101,6 +102,14 @@ public class DefaultModelValidator
         {
             Severity errOn30 = getSeverity( request, ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_0 );
 
+            // [MNG-6074] Maven should produce an error if no model version has been set in a POM file used to build an
+            // effective model.
+            //
+            // As of 3.4, the model version is mandatory even in raw models. The XML element still is optional in the
+            // XML schema and this will not change anytime soon. We do not want to build effective models based on
+            // models without a version starting with 3.4.
+            validateStringNotEmpty( "modelVersion", problems, Severity.ERROR, Version.V20, m.getModelVersion(), m );
+
             validateEnum( "modelVersion", problems, Severity.ERROR, Version.V20, m.getModelVersion(), null, m,
                           "4.0.0" );
 
@@ -157,23 +166,23 @@ public class DefaultModelValidator
                                   "must be unique but found duplicate profile with id " + profile.getId(), profile );
                 }
 
-                validate30RawProfileActivation( problems, profile.getActivation(), profile.getId(), prefix
-                    + ".activation", request );
+                validate30RawProfileActivation( problems, profile.getActivation(), profile.getId(),
+                                                prefix + ".activation", request );
 
                 validate20RawDependencies( problems, profile.getDependencies(), prefix + ".dependencies.dependency",
-                                         request );
+                                           request );
 
                 if ( profile.getDependencyManagement() != null )
                 {
-                    validate20RawDependencies( problems, profile.getDependencyManagement().getDependencies(), prefix
-                        + ".dependencyManagement.dependencies.dependency", request );
+                    validate20RawDependencies( problems, profile.getDependencyManagement().getDependencies(),
+                                               prefix + ".dependencyManagement.dependencies.dependency", request );
                 }
 
                 validateRawRepositories( problems, profile.getRepositories(), prefix + ".repositories.repository",
-                                      request );
+                                         request );
 
-                validateRawRepositories( problems, profile.getPluginRepositories(), prefix
-                    + ".pluginRepositories.pluginRepository", request );
+                validateRawRepositories( problems, profile.getPluginRepositories(),
+                                         prefix + ".pluginRepositories.pluginRepository", request );
 
                 BuildBase buildBase = profile.getBuild();
                 if ( buildBase != null )
@@ -184,7 +193,7 @@ public class DefaultModelValidator
                     if ( mngt != null )
                     {
                         validate20RawPlugins( problems, mngt.getPlugins(), prefix + ".pluginManagement.plugins.plugin",
-                                            request );
+                                              request );
                     }
                 }
             }
@@ -223,11 +232,8 @@ public class DefaultModelValidator
 
             if ( path.contains( "${project.basedir}" ) )
             {
-                addViolation( problems,
-                              Severity.WARNING,
-                              Version.V30,
-                              prefix + ( missing ? ".file.missing" : ".file.exists" ),
-                              null,
+                addViolation( problems, Severity.WARNING, Version.V30,
+                              prefix + ( missing ? ".file.missing" : ".file.exists" ), null,
                               "Failed to interpolate file location " + path + " for profile " + sourceHint
                                   + ": ${project.basedir} expression not supported during profile activation, "
                                   + "use ${basedir} instead",
@@ -235,15 +241,9 @@ public class DefaultModelValidator
             }
             else if ( hasProjectExpression( path ) )
             {
-                addViolation( problems,
-                              Severity.WARNING,
-                              Version.V30,
-                              prefix + ( missing ? ".file.missing" : ".file.exists" ),
-                              null,
-                              "Failed to interpolate file location "
-                                  + path
-                                  + " for profile "
-                                  + sourceHint
+                addViolation( problems, Severity.WARNING, Version.V30,
+                              prefix + ( missing ? ".file.missing" : ".file.exists" ), null,
+                              "Failed to interpolate file location " + path + " for profile " + sourceHint
                                   + ": ${project.*} expressions are not supported during profile activation",
                               file.getLocation( missing ? "missing" : "exists" ) );
             }
@@ -251,7 +251,7 @@ public class DefaultModelValidator
     }
 
     private void validate20RawPlugins( ModelProblemCollector problems, List<Plugin> plugins, String prefix,
-                                     ModelBuildingRequest request )
+                                       ModelBuildingRequest request )
     {
         Severity errOn31 = getSeverity( request, ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_1 );
 
@@ -259,6 +259,27 @@ public class DefaultModelValidator
 
         for ( Plugin plugin : plugins )
         {
+            if ( plugin.getGroupId() == null
+                || ( plugin.getGroupId() != null && plugin.getGroupId().trim().isEmpty() ) )
+            {
+                addViolation( problems, Severity.FATAL, Version.V20, prefix + ".(groupId:artifactId)", null,
+                              "groupId of a plugin must be defined. ", plugin );
+            }
+
+            if ( plugin.getArtifactId() == null
+                || ( plugin.getArtifactId() != null && plugin.getArtifactId().trim().isEmpty() ) )
+            {
+                addViolation( problems, Severity.FATAL, Version.V20, prefix + ".(groupId:artifactId)", null,
+                              "artifactId of a plugin must be defined. ", plugin );
+            }
+
+            // This will catch cases like <version></version> or <version/>
+            if ( plugin.getVersion() != null && plugin.getVersion().trim().isEmpty() )
+            {
+                addViolation( problems, Severity.FATAL, Version.V20, prefix + ".(groupId:artifactId)", null,
+                              "version of a plugin must be defined. ", plugin );
+            }
+
             String key = plugin.getKey();
 
             Plugin existing = index.get( key );
@@ -279,9 +300,9 @@ public class DefaultModelValidator
             {
                 if ( !executionIds.add( exec.getId() ) )
                 {
-                    addViolation( problems, Severity.ERROR, Version.V20, prefix + "[" + plugin.getKey()
-                        + "].executions.execution.id", null, "must be unique but found duplicate execution with id "
-                        + exec.getId(), exec );
+                    addViolation( problems, Severity.ERROR, Version.V20,
+                                  prefix + "[" + plugin.getKey() + "].executions.execution.id", null,
+                                  "must be unique but found duplicate execution with id " + exec.getId(), exec );
                 }
             }
         }
@@ -302,9 +323,8 @@ public class DefaultModelValidator
         {
             if ( !"pom".equals( m.getPackaging() ) )
             {
-                addViolation( problems, Severity.ERROR, Version.BASE, "packaging", null,
-                              "with value '" + m.getPackaging() + "' is invalid. Aggregator projects "
-                                  + "require 'pom' as packaging.", m );
+                addViolation( problems, Severity.ERROR, Version.BASE, "packaging", null, "with value '"
+                    + m.getPackaging() + "' is invalid. Aggregator projects " + "require 'pom' as packaging.", m );
             }
 
             for ( int i = 0, n = m.getModules().size(); i < n; i++ )
@@ -364,8 +384,8 @@ public class DefaultModelValidator
                     validate20PluginVersion( "build.plugins.plugin.version", problems, p.getVersion(), p.getKey(), p,
                                              request );
 
-                    validateBoolean( "build.plugins.plugin.inherited", problems, errOn30, Version.V20,
-                                     p.getInherited(), p.getKey(), p );
+                    validateBoolean( "build.plugins.plugin.inherited", problems, errOn30, Version.V20, p.getInherited(),
+                                     p.getKey(), p );
 
                     validateBoolean( "build.plugins.plugin.extensions", problems, errOn30, Version.V20,
                                      p.getExtensions(), p.getKey(), p );
@@ -414,7 +434,7 @@ public class DefaultModelValidator
                 validate20EffectiveRepository( problems, distMgmt.getRepository(), "distributionManagement.repository",
                                                request );
                 validate20EffectiveRepository( problems, distMgmt.getSnapshotRepository(),
-                                    "distributionManagement.snapshotRepository", request );
+                                               "distributionManagement.snapshotRepository", request );
             }
         }
     }
@@ -458,7 +478,8 @@ public class DefaultModelValidator
                     {
                         addViolation( problems, Severity.WARNING, Version.V20, prefix + ".systemPath", key,
                                       "should not point at files within the project directory, " + sysPath
-                                          + " will be unresolvable by dependent projects", dependency );
+                                          + " will be unresolvable by dependent projects",
+                                      dependency );
                     }
                 }
             }
@@ -470,15 +491,13 @@ public class DefaultModelValidator
                 String msg;
                 if ( equals( existing.getVersion(), dependency.getVersion() ) )
                 {
-                    msg =
-                        "duplicate declaration of version "
-                            + StringUtils.defaultString( dependency.getVersion(), "(?)" );
+                    msg = "duplicate declaration of version "
+                        + StringUtils.defaultString( dependency.getVersion(), "(?)" );
                 }
                 else
                 {
-                    msg =
-                        "version " + StringUtils.defaultString( existing.getVersion(), "(?)" ) + " vs "
-                            + StringUtils.defaultString( dependency.getVersion(), "(?)" );
+                    msg = "version " + StringUtils.defaultString( existing.getVersion(), "(?)" ) + " vs "
+                        + StringUtils.defaultString( dependency.getVersion(), "(?)" );
                 }
 
                 addViolation( problems, errOn31, Version.V20, prefix + ".(groupId:artifactId:type:classifier)", null,
@@ -513,8 +532,8 @@ public class DefaultModelValidator
                                      d.getManagementKey(), d );
 
                     /*
-                     * TODO: Extensions like Flex Mojos use custom scopes like "merged", "internal", "external", etc.
-                     * In order to don't break backward-compat with those, only warn but don't error out.
+                     * TODO: Extensions like Flex Mojos use custom scopes like "merged", "internal", "external", etc. In
+                     * order to don't break backward-compat with those, only warn but don't error out.
                      */
                     validateEnum( prefix + "scope", problems, Severity.WARNING, Version.V20, d.getScope(),
                                   d.getManagementKey(), d, "provided", "compile", "runtime", "test", "system" );
@@ -591,8 +610,8 @@ public class DefaultModelValidator
                     {
                         msg += ". Please verify that you run Maven using a JDK and not just a JRE.";
                     }
-                    addViolation( problems, Severity.WARNING, Version.BASE, prefix + "systemPath",
-                                  d.getManagementKey(), msg, d );
+                    addViolation( problems, Severity.WARNING, Version.BASE, prefix + "systemPath", d.getManagementKey(),
+                                  msg, d );
                 }
             }
         }
@@ -628,7 +647,7 @@ public class DefaultModelValidator
     }
 
     /**
-     * @since 3.2.4 
+     * @since 3.2.4
      */
     protected void validateDependencyVersion( ModelProblemCollector problems, Dependency d, String prefix )
     {
@@ -637,7 +656,7 @@ public class DefaultModelValidator
     }
 
     private void validateRawRepositories( ModelProblemCollector problems, List<Repository> repositories, String prefix,
-                                       ModelBuildingRequest request )
+                                          ModelBuildingRequest request )
     {
         Map<String, Repository> index = new HashMap<>();
 
@@ -657,9 +676,8 @@ public class DefaultModelValidator
             {
                 Severity errOn30 = getSeverity( request, ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_0 );
 
-                addViolation( problems, errOn30, Version.V20, prefix + ".id", null,
-                              "must be unique: " + repository.getId() + " -> " + existing.getUrl() + " vs "
-                                  + repository.getUrl(), repository );
+                addViolation( problems, errOn30, Version.V20, prefix + ".id", null, "must be unique: "
+                    + repository.getId() + " -> " + existing.getUrl() + " vs " + repository.getUrl(), repository );
             }
             else
             {
@@ -669,7 +687,7 @@ public class DefaultModelValidator
     }
 
     private void validate20EffectiveRepository( ModelProblemCollector problems, Repository repository, String prefix,
-                                     ModelBuildingRequest request )
+                                                ModelBuildingRequest request )
     {
         if ( repository != null )
         {
@@ -680,9 +698,10 @@ public class DefaultModelValidator
 
             if ( "local".equals( repository.getId() ) )
             {
-                addViolation( problems, errOn31, Version.V20, prefix + ".id", null, "must not be 'local'"
-                    + ", this identifier is reserved for the local repository"
-                    + ", using it for other repositories will corrupt your repository metadata.", repository );
+                addViolation( problems, errOn31, Version.V20, prefix + ".id", null,
+                              "must not be 'local'" + ", this identifier is reserved for the local repository"
+                                  + ", using it for other repositories will corrupt your repository metadata.",
+                              repository );
             }
 
             if ( "legacy".equals( repository.getLayout() ) )
@@ -694,7 +713,7 @@ public class DefaultModelValidator
     }
 
     private void validate20RawResources( ModelProblemCollector problems, List<Resource> resources, String prefix,
-                                    ModelBuildingRequest request )
+                                         ModelBuildingRequest request )
     {
         Severity errOn30 = getSeverity( request, ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_0 );
 
@@ -730,8 +749,8 @@ public class DefaultModelValidator
             boolean match = ID_REGEX.matcher( id ).matches();
             if ( !match )
             {
-                addViolation( problems, severity, version, fieldName, sourceHint, "with value '" + id
-                    + "' does not match a valid id pattern.", tracker );
+                addViolation( problems, severity, version, fieldName, sourceHint,
+                              "with value '" + id + "' does not match a valid id pattern.", tracker );
             }
             return match;
         }
@@ -750,14 +769,13 @@ public class DefaultModelValidator
             boolean match = ID_WITH_WILDCARDS_REGEX.matcher( id ).matches();
             if ( !match )
             {
-                addViolation( problems, severity, version, fieldName, sourceHint, "with value '" + id
-                    + "' does not match a valid id pattern.", tracker );
+                addViolation( problems, severity, version, fieldName, sourceHint,
+                              "with value '" + id + "' does not match a valid id pattern.", tracker );
             }
             return match;
         }
     }
 
-
     private boolean validateStringNoExpression( String fieldName, ModelProblemCollector problems, Severity severity,
                                                 Version version, String string, InputLocationTracker tracker )
     {
@@ -876,8 +894,8 @@ public class DefaultModelValidator
             return true;
         }
 
-        addViolation( problems, severity, version, fieldName, sourceHint, "must be 'true' or 'false' but is '" + string
-            + "'.", tracker );
+        addViolation( problems, severity, version, fieldName, sourceHint,
+                      "must be 'true' or 'false' but is '" + string + "'.", tracker );
 
         return false;
     }
@@ -898,8 +916,8 @@ public class DefaultModelValidator
             return true;
         }
 
-        addViolation( problems, severity, version, fieldName, sourceHint, "must be one of " + values + " but is '"
-            + string + "'.", tracker );
+        addViolation( problems, severity, version, fieldName, sourceHint,
+                      "must be one of " + values + " but is '" + string + "'.", tracker );
 
         return false;
     }
@@ -916,7 +934,8 @@ public class DefaultModelValidator
                 {
                     addViolation( problems, severity, version, fieldName, sourceHint,
                                   "must not contain any of these characters " + banned + " but found "
-                                      + string.charAt( i ), tracker );
+                                      + string.charAt( i ),
+                                  tracker );
                     return false;
                 }
             }
@@ -983,8 +1002,8 @@ public class DefaultModelValidator
 
         if ( string.length() <= 0 || "RELEASE".equals( string ) || "LATEST".equals( string ) )
         {
-            addViolation( problems, errOn30, Version.V20, fieldName, sourceHint, "must be a valid version but is '"
-                + string + "'.", tracker );
+            addViolation( problems, errOn30, Version.V20, fieldName, sourceHint,
+                          "must be a valid version but is '" + string + "'.", tracker );
             return false;
         }
 
@@ -1005,8 +1024,11 @@ public class DefaultModelValidator
 
         buffer.append( ' ' ).append( message );
 
-        problems.add( new ModelProblemCollectorRequest( severity, version )
-            .setMessage( buffer.toString() ).setLocation( getLocation( fieldName, tracker ) ) );
+        // CHECKSTYLE_OFF: LineLength
+        problems.add( new ModelProblemCollectorRequest( severity,
+                                                        version ).setMessage( buffer.toString() ).setLocation( getLocation( fieldName,
+                                                                                                                            tracker ) ) );
+        // CHECKSTYLE_ON: LineLength
     }
 
     private static InputLocation getLocation( String fieldName, InputLocationTracker tracker )

http://git-wip-us.apache.org/repos/asf/maven/blob/017dcaf2/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java
----------------------------------------------------------------------
diff --git a/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java b/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java
index dde532d..8525476 100644
--- a/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java
+++ b/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java
@@ -163,7 +163,8 @@ public class DefaultModelValidatorTest
 
         assertEquals( "'groupId' with value 'o/a/m' does not match a valid id pattern.", result.getErrors().get( 0 ) );
 
-        assertEquals( "'artifactId' with value 'm$-do$' does not match a valid id pattern.", result.getErrors().get( 1 ) );
+        assertEquals( "'artifactId' with value 'm$-do$' does not match a valid id pattern.",
+                      result.getErrors().get( 1 ) );
     }
 
     public void testMissingType()
@@ -203,8 +204,7 @@ public class DefaultModelValidatorTest
 
         assertViolations( result, 0, 1, 0 );
 
-        assertTrue( result.getErrors().get( 0 ).contains(
-            "'dependencies.dependency.artifactId' for groupId:null:jar is missing" ) );
+        assertTrue( result.getErrors().get( 0 ).contains( "'dependencies.dependency.artifactId' for groupId:null:jar is missing" ) );
     }
 
     public void testMissingDependencyGroupId()
@@ -214,8 +214,7 @@ public class DefaultModelValidatorTest
 
         assertViolations( result, 0, 1, 0 );
 
-        assertTrue( result.getErrors().get( 0 ).contains(
-            "'dependencies.dependency.groupId' for null:artifactId:jar is missing" ) );
+        assertTrue( result.getErrors().get( 0 ).contains( "'dependencies.dependency.groupId' for null:artifactId:jar is missing" ) );
     }
 
     public void testMissingDependencyVersion()
@@ -225,8 +224,7 @@ public class DefaultModelValidatorTest
 
         assertViolations( result, 0, 1, 0 );
 
-        assertTrue( result.getErrors().get( 0 ).contains(
-            "'dependencies.dependency.version' for groupId:artifactId:jar is missing" ) );
+        assertTrue( result.getErrors().get( 0 ).contains( "'dependencies.dependency.version' for groupId:artifactId:jar is missing" ) );
     }
 
     public void testMissingDependencyManagementArtifactId()
@@ -236,8 +234,7 @@ public class DefaultModelValidatorTest
 
         assertViolations( result, 0, 1, 0 );
 
-        assertTrue( result.getErrors().get( 0 ).contains(
-            "'dependencyManagement.dependencies.dependency.artifactId' for groupId:null:jar is missing" ) );
+        assertTrue( result.getErrors().get( 0 ).contains( "'dependencyManagement.dependencies.dependency.artifactId' for groupId:null:jar is missing" ) );
     }
 
     public void testMissingDependencyManagementGroupId()
@@ -247,8 +244,7 @@ public class DefaultModelValidatorTest
 
         assertViolations( result, 0, 1, 0 );
 
-        assertTrue( result.getErrors().get( 0 ).contains(
-            "'dependencyManagement.dependencies.dependency.groupId' for null:artifactId:jar is missing" ) );
+        assertTrue( result.getErrors().get( 0 ).contains( "'dependencyManagement.dependencies.dependency.groupId' for null:artifactId:jar is missing" ) );
     }
 
     public void testMissingAll()
@@ -555,7 +551,8 @@ public class DefaultModelValidatorTest
     public void testBadDependencyExclusionId()
         throws Exception
     {
-        SimpleProblemCollector result = validateEffective( "bad-dependency-exclusion-id.xml", ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 );
+        SimpleProblemCollector result =
+            validateEffective( "bad-dependency-exclusion-id.xml", ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 );
 
         assertViolations( result, 0, 0, 2 );
 
@@ -620,6 +617,57 @@ public class DefaultModelValidatorTest
             + "should not point at files within the project directory" );
     }
 
+    public void testInvalidVersionInPluginManagement()
+        throws Exception
+    {
+        SimpleProblemCollector result = validateRaw( "raw-model/missing-plugin-version-pluginManagement.xml" );
+
+        assertViolations( result, 1, 0, 0 );
+
+        assertEquals( "'build.pluginManagement.plugins.plugin.(groupId:artifactId)' version of a plugin must be defined. ",
+                      result.getFatals().get( 0 ) );
+
+    }
+
+    public void testInvalidGroupIdInPluginManagement()
+        throws Exception
+    {
+        SimpleProblemCollector result = validateRaw( "raw-model/missing-groupId-pluginManagement.xml" );
+
+        assertViolations( result, 1, 0, 0 );
+
+        assertEquals( "'build.pluginManagement.plugins.plugin.(groupId:artifactId)' groupId of a plugin must be defined. ",
+                      result.getFatals().get( 0 ) );
+
+    }
+
+    public void testInvalidArtifactIdInPluginManagement()
+        throws Exception
+    {
+        SimpleProblemCollector result = validateRaw( "raw-model/missing-artifactId-pluginManagement.xml" );
+
+        assertViolations( result, 1, 0, 0 );
+
+        assertEquals( "'build.pluginManagement.plugins.plugin.(groupId:artifactId)' artifactId of a plugin must be defined. ",
+                      result.getFatals().get( 0 ) );
+
+    }
+
+    public void testInvalidGroupAndArtifactIdInPluginManagement()
+        throws Exception
+    {
+        SimpleProblemCollector result = validateRaw( "raw-model/missing-ga-pluginManagement.xml" );
+
+        assertViolations( result, 2, 0, 0 );
+
+        assertEquals( "'build.pluginManagement.plugins.plugin.(groupId:artifactId)' groupId of a plugin must be defined. ",
+                      result.getFatals().get( 0 ) );
+
+        assertEquals( "'build.pluginManagement.plugins.plugin.(groupId:artifactId)' artifactId of a plugin must be defined. ",
+                      result.getFatals().get( 1 ) );
+
+    }
+
     public void testMissingReportPluginVersion()
         throws Exception
     {
@@ -627,4 +675,5 @@ public class DefaultModelValidatorTest
 
         assertViolations( result, 0, 0, 0 );
     }
+
 }

http://git-wip-us.apache.org/repos/asf/maven/blob/017dcaf2/maven-model-builder/src/test/resources/poms/validation/raw-model/missing-artifactId-pluginManagement.xml
----------------------------------------------------------------------
diff --git a/maven-model-builder/src/test/resources/poms/validation/raw-model/missing-artifactId-pluginManagement.xml b/maven-model-builder/src/test/resources/poms/validation/raw-model/missing-artifactId-pluginManagement.xml
new file mode 100644
index 0000000..194abf8
--- /dev/null
+++ b/maven-model-builder/src/test/resources/poms/validation/raw-model/missing-artifactId-pluginManagement.xml
@@ -0,0 +1,39 @@
+<!--
+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/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.example.group</groupId>
+  <artifactId>testinvalidpom</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>the.groupId.Of.This.Plugin</groupId>
+          <artifactId/>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/maven/blob/017dcaf2/maven-model-builder/src/test/resources/poms/validation/raw-model/missing-ga-pluginManagement.xml
----------------------------------------------------------------------
diff --git a/maven-model-builder/src/test/resources/poms/validation/raw-model/missing-ga-pluginManagement.xml b/maven-model-builder/src/test/resources/poms/validation/raw-model/missing-ga-pluginManagement.xml
new file mode 100644
index 0000000..4058dd6
--- /dev/null
+++ b/maven-model-builder/src/test/resources/poms/validation/raw-model/missing-ga-pluginManagement.xml
@@ -0,0 +1,39 @@
+<!--
+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/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.example.group</groupId>
+  <artifactId>testinvalidpom</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId></groupId>
+          <artifactId/>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/maven/blob/017dcaf2/maven-model-builder/src/test/resources/poms/validation/raw-model/missing-groupId-pluginManagement.xml
----------------------------------------------------------------------
diff --git a/maven-model-builder/src/test/resources/poms/validation/raw-model/missing-groupId-pluginManagement.xml b/maven-model-builder/src/test/resources/poms/validation/raw-model/missing-groupId-pluginManagement.xml
new file mode 100644
index 0000000..f3f23e6
--- /dev/null
+++ b/maven-model-builder/src/test/resources/poms/validation/raw-model/missing-groupId-pluginManagement.xml
@@ -0,0 +1,39 @@
+<!--
+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/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.example.group</groupId>
+  <artifactId>testinvalidpom</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId></groupId>
+          <artifactId>this-is-the-artifact</artifactId>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/maven/blob/017dcaf2/maven-model-builder/src/test/resources/poms/validation/raw-model/missing-plugin-version-pluginManagement.xml
----------------------------------------------------------------------
diff --git a/maven-model-builder/src/test/resources/poms/validation/raw-model/missing-plugin-version-pluginManagement.xml b/maven-model-builder/src/test/resources/poms/validation/raw-model/missing-plugin-version-pluginManagement.xml
new file mode 100644
index 0000000..94b1777
--- /dev/null
+++ b/maven-model-builder/src/test/resources/poms/validation/raw-model/missing-plugin-version-pluginManagement.xml
@@ -0,0 +1,40 @@
+<!--
+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/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.example.group</groupId>
+  <artifactId>testinvalidpom</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>the.group.id</groupId>
+          <artifactId>the.artifact</artifactId>
+          <version/>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+</project>
\ No newline at end of file