当前位置: 首页 > news >正文

Maven中的扁平化POM

Author:  Jia, Weigang.

Maven中的POM大致有两个目的:

  1. 开发人员用POM编译和发布构件
  2. 被其他项目用于依赖管理

对于第一个目的,POM中的关于编译和发布的元素都是有意义的。对于第二个目的,POM中的关于编译和发布的元素就没有意义了。比如,一个项目A依赖于构件B,项目A仅仅需要知道构件B的GroupId、ArtifactId、Version以及构件B的依赖,其他的元素意义都不是很大。

Maven的发布方式是把编译时的POM直接拷贝到远程仓库。这样对于构件的用户而言,他们将看到编译时期POM的各种元素。如果POM有多层父POM,用户也会看到。父POM中可能定义了许多<dependencyManagement>,如果用户需要确定一个依赖的版本,可能需要一层一层的向上层父POM查找,比较繁琐。

对于开发人员编译和发布时使用的POM应该和构件使用者的POM有所不同,对于后者,他们只需要关心构件的GroupId、ArtifactId、Version以及构件的依赖。扁平化POM可以解决这个问题,在扁平化POM中只有构件的GroupId、ArtifactId、Version以及构件的依赖,没有Parent元素。对于每个构件的依赖,它的Version都是被解析过的。

下面详细讨论扁平POM中的元素:

元素

在扁平化POM中变换

注释

modelVersion

“4.0.0”

固定值

groupId

artifactId

version

packaging

被解析过

可能从父POM中解析version

dependencies

被解析过

可能从父POM的<dependencyManagement>中解析出dependencies的所有属性(主要是version)。Scope是test的dependency将会被移除

Other Elements

被移除

构件的用户不关心这些元素

 

  我扩展了maven-deploy-plugin ,增加了一个enableFlatPom参数来实现了扁平化POM,如果这个参数的值是true,maven-deploy-plugin会生成扁平化POM并把它设置成当前项目的POM,然后发布到远程仓库。

 

下面是一个扁平化POM的例子:

原始的父POM


<project>

  <modelVersion>4.0.0</modelVersion>

  <groupId>com.ebay.test</groupId>

  <artifactId>webtestjavaParent</artifactId>

  <version>1.0.0-SNAPSHOT</version>

  <packaging>pom</packaging>

  <properties>

    <webtestjava.version>1.0.0-SNAPSHOT<webtestjava.version>

  </properties>

  <modules>

    <module>webtest-java</module>

  </modules>

  <dependencyManagement>

    <dependencies>

      <dependency>

        <groupId>junit</groupId>

        <artifactId>junit</artifactId>

        <version>4.10</version>

      </dependency>

      <dependency>

        <groupId>log4j</groupId>

        <artifactId>log4j</artifactId>

        <version>1.2.17</version>     

      </dependency>

    </dependencies>

  </dependencyManagement>

  <build>

           <plugins>

                  <plugin>

                        <groupId>org.apache.maven.plugins</groupId>

                   <artifactId>maven-deploy-plugin</artifactId>

                   <version>2.9-SNAPSHOT</version>

                   <configuration>

                                <enableFlatPom>true</enableFlatPom>

                         </configuration>

               </plugin>

           </plugins>

    </build>

</project>


原始的子POM

<project>

  <modelVersion>4.0.0</modelVersion>

  <parent>

    <groupId>com.ebay.test</groupId>

    <artifactId>webtestjavaParent</artifactId>

    <version>1.0.0-SNAPSHOT</version>

  </parent>

  <artifactId>webtestjava</artifactId>

  <version>${webtestjava.version}</version>

  <packaging>jar</packaging>

  <dependencies>

    <!-- Internal dependencies with project version -->

    <dependency>

      <groupId>com.ebay.test</groupId>

      <artifactId>webtestjava-module2</artifactId>

      <version>${webtestjava.version}</version>

    </dependency>

 

    <!-- External dependencies with managed version -->

    <dependency>

      <groupId>log4j</groupId>

      <artifactId>log4j</artifactId>

    </dependency>

    <dependency>

      <groupId>junit</groupId>

      <artifactId>junit</artifactId>

      <scope>test</scope>

    </dependency>

  </dependencies>

</project>


扁平化POM

<project>

  <modelVersion>4.0.0</modelVersion>

  <groupId>com.ebay.test</groupId>

  <artifactId>webtestjava</artifactId>

  <version>1.0.0-SNAPSHOT</version>

  <packaging>jar</packaging>

  <dependencies>

    <dependency>

      <groupId>com.ebay.test</groupId>

      <artifactId>webtestjava-module2</artifactId>

      <version>1.0.0-SNAPSHOT</version>

    </dependency>

    <dependency>

      <groupId>log4j</groupId>

      <artifactId>log4j</artifactId>

      <version>1.2.17</version>     

    </dependency>

  </dependencies>

</project>


扁平化POM实现:

修改maven-deploy-plugin中的类org.apache.maven.plugin.deploy. DeployMojo。

1. 增加enableFlatPom参数:

    @Parameter( property = "enableFlatPom", defaultValue = "false" )

    private boolean enableFlatPom;

2.当enableFlatPom参数设置为true的时候,生成扁平化的POM并设置为当前项目的POM。

   if ( enableFlatPom )

   {

       useFlatPom( request.getProject() );

       artifact = request.getProject().getArtifact();

       pomFile = request.getProject().getFile();

    }

   private void useFlatPom( MavenProject project )

        throws MojoExecutionException

   {

      generateFlatPom( project );

      applyFlatPom( project );

   }

3.useFlatPom方法会生成扁平化的POM并设置为当前项目的POM,createFlatPomFile方法生成一个空的POM文件,createFlatModel方法生成扁平化POM的模型,然后把扁平化POM的模型写入到POM文件。

   private void generateFlatPom( MavenProject project )

        throws MojoExecutionException

   {

 getLog().info( "Generating flat pom for project " + project.getName() );

 File flatPomFile = createFlatPomFile( project );

 Model flatPomModel = createFlatModel( project );

 MavenXpp3Writer pomWriter = new MavenXpp3Writer();

 Writer fileWriter = null;

try

{

      fileWriter = WriterFactory.newXmlWriter( flatPomFile );

      pomWriter.write( fileWriter, flatPomModel );

}

 catch ( IOException e )

{

throw new MojoExecutionException( "Cannot write to flat pom file for project " + project.getName(), e );

}

finally

{

      IOUtil.close( fileWriter );

}

}

4. applyFlatPom方法将扁平化POM设置为当前项目的POM并更新相应元数据。

private void applyFlatPom( MavenProject project )

        throws MojoExecutionException

{

  getLog().info( "Applying flat pom for project " + project.getName() );

  File flatPomFile = new File( getFlatPomDir( project.getBasedir() ), "pom.xml" );

  if ( !flatPomFile.exists() )

  {

      throw new MojoExecutionException( "Cannot find flat pom file in path " + flatPomFile.getAbsolutePath()+ " for project " + project.getName() );

  }

  project.setFile( flatPomFile );

  Artifact artifact = ArtifactUtils.copyArtifact( project.getArtifact() );

  Collection metadataList = project.getArtifact().getMetadataList();

  for ( ArtifactMetadata metadata : (Collection<ArtifactMetadata>) metadataList )

  {

       if ( metadata instanceof RepositoryMetadata )

       {

           artifact.addMetadata( metadata );

       }

  }

  artifact.addMetadata( new ProjectArtifactMetadata( artifact, flatPomFile ) );

  project.setArtifact( artifact );

}

 

扁平化POM是原始POM的精简版,它的目标用户是构件的使用者,所以对于项目的开发和编译发布的元素都会被移除。将扁平POM发布到远程仓库中将会对构件用户更加友好。

相关文章:

  • 你好,HBase
  • Maven Build Tracking
  • 分布式文件系统概述
  • 调试Oracle 之一 基础篇
  • 基于Apache Mesos 构建高可靠,高可用的Jenkins CI
  • Kepler性能分析之M2E调优
  • Ebay开源 Pulsar:实时大数据分析平台
  • JS组件化验证检测
  • 基于云技术的集成测试代码覆盖率收集的一站式解决方案
  • 使用github pages + issues + api建立个人博客
  • MapReduce的详细过程
  • 基于Jmeter和Jenkins的自动化性能测试的一站式解决方案
  • jQuery动态载入JS文件研究
  • SolrCloud之分布式索引及与Zookeeper的集成
  • Kafka的分布式架构设计与High Availability机制
  • 【从零开始安装kubernetes-1.7.3】2.flannel、docker以及Harbor的配置以及作用
  • Angularjs之国际化
  • js ES6 求数组的交集,并集,还有差集
  • Node项目之评分系统(二)- 数据库设计
  • Python3爬取英雄联盟英雄皮肤大图
  • Sublime Text 2/3 绑定Eclipse快捷键
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • TypeScript实现数据结构(一)栈,队列,链表
  • 不上全站https的网站你们就等着被恶心死吧
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 蓝海存储开关机注意事项总结
  • 数组大概知多少
  • 用Canvas画一棵二叉树
  • 字符串匹配基础上
  • 自制字幕遮挡器
  • 阿里云移动端播放器高级功能介绍
  • #etcd#安装时出错
  • #pragam once 和 #ifndef 预编译头
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • (Bean工厂的后处理器入门)学习Spring的第七天
  • (MIT博士)林达华老师-概率模型与计算机视觉”
  • (补)B+树一些思想
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (一)C语言之入门:使用Visual Studio Community 2022运行hello world
  • (转)Groupon前传:从10个月的失败作品修改,1个月找到成功
  • (转)IOS中获取各种文件的目录路径的方法
  • .NET/C# 使用 ConditionalWeakTable 附加字段(CLR 版本的附加属性,也可用用来当作弱引用字典 WeakDictionary)
  • .NET/C# 项目如何优雅地设置条件编译符号?
  • .net生成的类,跨工程调用显示注释
  • .NET性能优化(文摘)
  • [ C++ ] template 模板进阶 (特化,分离编译)
  • [ vulhub漏洞复现篇 ] Apache Flink目录遍历(CVE-2020-17519)
  • [ABC294Ex] K-Coloring
  • [Android]常见的数据传递方式
  • [Angular] 笔记 21:@ViewChild
  • [BetterExplained]书写是为了更好的思考(转载)