如何使依赖冲突的maven失败

时间:2012-02-01 18:26:23

标签: maven-2 locking dependencies

我正在开发一个大型多模块项目,该项目使用内部框架作为其依赖项之一。框架版本在项目开始时设置在顶层pom中,并且必须保持不变。如果任何子模块使用不同的版本,我希望构建失败。

我尝试将依赖声明为单个版本:

<dependency>
  <groupId>framework_snt</groupId>
  <artifactId>SFP</artifactId>
  <version>[6.1]</version>
  <type>pom</type>
</dependency>

我尝试使用带有禁止依赖项的enforcer插件:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-enforcer-plugin</artifactId>
  <version>1.0.1</version>
  <executions>
    <execution>
      <id>enforce-versions</id>
      <goals>
        <goal>enforce</goal>
      </goals>
      <configuration>
        <rules>
          <requireJavaVersion>
            <version>[1.6.0-21]</version>
          </requireJavaVersion>
          <requireMavenVersion>
            <version>[3.0.3]</version>
          </requireMavenVersion>
          <bannedDependencies>
            <excludes>
              <exclude>framework_snt:SFP</exclude>
            </excludes>
            <includes>
              <include>framework_snt:SFP:6.1.2</include>
            </includes>
          </bannedDependencies>
        </rules>
      </configuration>
    </execution>
  </executions>
</plugin>

我还尝试添加<DependencyConvergence/>标记here,但这些方法都不起作用。



所以考虑到这个顶级pom片段:

<project>
  <groupId>glb</groupId>
  <artifactId>GLB</artifactId>
  <packaging>pom</packaging>
  <name>Global</name>
  <version>1.0</version>
  ........
  <dependencies>
    <dependency>
      <groupId>framework_snt</groupId>
      <artifactId>SFP</artifactId>
      <version>[6.1.2]</version>
      <type>pom</type>
    </dependency>
  </dependencies>  
  .....
</project>

这个(无效的)子模块:

<project>
  <groupId>glb</groupId>
  <artifactId>CORE</artifactId>
  <packaging>jar</packaging>
  <name>Core</name>
  <version>1.0</version>

  <parent>
    <groupId>glb</groupId>
    <artifactId>GLB</artifactId>
    <version>1.0</version>
  </parent>

  <dependencies>
    <dependency>
      <groupId>framework_snt</groupId>
      <artifactId>SFP</artifactId>
      <version>6.3</version>
      <type>pom</type>
    </dependency>
  </dependencies>
</project>

如何设置maven以便在使用上面的子模块时构建将失败,但是当我删除标记<version>6.3</version>时它成功(或者我更改版本以匹配顶级pom中的那个?< / p>

1 个答案:

答案 0 :(得分:0)

经过多次搜索和尝试使用各种插件并无处可寻,我决定编写自己的插件来进行冲突检查。使用依赖:树插件源作为基础我写了以下内容:

   /**
    * Walks the dependency tree looking for anything marked as a conflict, and fails the build if one is found
    * code ripped from the dependency:tree plugin
    *
    * @param rootNode
    * the dependency tree root node to check
    *
    */
   private void checkForConflicts( DependencyNode rootNode ) throws MojoExecutionException
   {
   StringWriter writer = new StringWriter();
   boolean conflicts=false;

   // build the tree
   DependencyNodeVisitor visitor = new SerializingDependencyNodeVisitor( writer, SerializingDependencyNodeVisitor.STANDARD_TOKENS);
   visitor = new BuildingDependencyNodeVisitor( visitor );
   rootNode.accept( visitor );

   getLog().debug("Root: "+rootNode.toNodeString() );

   DependencyNode node;
   Artifact actual, conflict;
   DependencyTreeInverseIterator iter = new DependencyTreeInverseIterator(rootNode);
   while (iter.hasNext() )
     {
      node = (DependencyNode)iter.next();
      if (node.getState() == DependencyNode.OMITTED_FOR_CONFLICT)
        {
         actual = node.getArtifact();
         conflict = node.getRelatedArtifact();
         getLog().debug("conflict node: " + node.toNodeString() );
         getLog().debug("conflict with: "+conflict.toString() );

         getLog().error(actual.getGroupId()+":"+actual.getArtifactId()+":"+actual.getType()+" Conflicting versions: "+actual.getVersion()+" and "+conflict.getVersion() );
         conflicts=true;
        }
     }

    if (conflicts)
      throw new MojoExecutionException( "version conflict detected");
   }

您可以使用以下内容从现有插件中调用此方法:

try
  {
   rootNode = dependencyTreeBuilder.buildDependencyTree( project, localRepository, artifactFactory, artifactMetadataSource, null, artifactCollector );
   checkForConflicts( rootNode );
  }
catch ( DependencyTreeBuilderException e)
  {
   throw new MojoExecutionException( "Cannot build project dependency tree", e);
  }

然后在你的插件pom.xml中,包含来自现有依赖项插件源的依赖项以及你的好处。

这适用于我们的项目 - 但如果有人知道更清洁或更好的方式,请告诉我。