zoukankan      html  css  js  c++  java
  • Maven原型骨架及常见问题


    关于Maven原型工程的制作就不在这里详细介绍了,具体细节请参考之前的文章: 定制Maven原型生成项目
    下面分享制作和使用Maven原型工程时碰到的常见问题,以及原型的上传和使用方法。



    1.模块路径问题

    1.1 路径问题

    在使用原型工程时会碰到下面的错误:

    1
    2
    org.apache.maven.archetype.exception.ArchetypeGenerationFailure: 
    Error merging velocity templates: Unable to find resource 'archetype-resources/__rootArtifactId__-aggregator/../__rootArtifactId__-common/pom.xml'

    如果使用maven-archetype-plugin的2.0-alpha-4版,则在【第三步】从原型快速生成项目时才会报错;如果使用2.2版,则在【第二步】编译原型Jar包时就会报错。
    出现这个问题的原因是我的工程的目录结构:


    根目录下的pom.xml中定义module:

    1
    2
    3
         < modules >
             < module >xyz-aggregator</ module >
         </ modules >

    xyz-aggregator的pom.xml中定义module:

    1
    2
    3
    4
         < modules >
             < module >../xyz-common</ module >
             < module >../xyz-web</ module >
         </ modules >

    也就是说实际上aggregator包含common和web工程,但目录结构上却是平级。这种结构比较扁平化,结构上比较清晰。
    但Maven的archetype插件要求module中的路径与module名字必须一致。对于这个问题,Maven的JIRA上已经有人报告 issue了,但还未得到解决了。

    1.2 元数据

    碰到这种问题,我们使用2.0-alpha-4版的先生成出原型,再手动修改Archetype插件的元数据了。
    在我们对原型工程执行archetype:create-from-project后,会在target目录下生成许多东西。

    target/
    └── generated-sources
        └── archetype
            ├── pom.xml
            └── src
                └── main
                    └── resources
                        ├── archetype-resources
                        │   ├── __rootArtifactId__-aggregator
                        │   │   └── pom.xml
                        │   ├── __rootArtifactId__-common
                        │   │   ├── pom.xml
                        │   │   └── src
                        │   ├── __rootArtifactId__-web
                        │   │   ├── pom.xml
                        │   │   └── src
                        │   ├── pom.xml
                        │   └── quick-start.bat
                        └── META-INF
                            └── maven
                                ├── archetype.xml
                                └── archetype-metadata.xml

    target/generated-sources/archetype就是我们从一个普通项目产生的原型。src存放的是原型项目的源码,其实就是将源项目中的项目名、包名等都替换为占位符。
    要注意的是pom.xml中module间的包含关系都被去掉了,保存在了META-INF/maven/archetype-metadata.xml中,这个文件就是我们要修改的元数据。

    这里介绍几个关键的结点。<fileset>是要包含的文件,filtered="true"表示该fileset中的文件在生成项目时要进行占位符替换。
    <modules>里包含各个module及module中包含的fileset。

    3.解决方案

    针对module工程的路径问题,我们可以将common和web工程从<modules>中提取出来,作为普通的<fileset>文件进行占位符替换。
    并将aggregator工程的pom.xml中的module手动添加上,因为Archetype插件是根据<modules>在生成项目时添加上module的。
    (不太清楚为什么要在原型工程中把module都去掉,在生成时再重新添加上?)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    <? xml  version = "1.0"  encoding = "UTF-8" ?>< archetype-descriptor  name = "basic" >
       < fileSets >
         < fileSet  filtered = "true"  encoding = "UTF-8" >
           < directory ></ directory >
           < includes >
             < include >README.txt</ include >
           </ includes >
         </ fileSet >
         < fileSet  filtered = "true"  encoding = "UTF-8" >
           < directory ></ directory >
           < includes >
             < include >quick-start.bat</ include >
           </ includes >
         </ fileSet >
         < fileSet  filtered = "true"  packaged = "true"  encoding = "UTF-8" >
           < directory >__rootArtifactId__-common/src/main/java</ directory >
           < includes >
             < include >**/*.java</ include >
           </ includes >
         </ fileSet >
         < fileSet  packaged = "true"  encoding = "UTF-8" >
           < directory >__rootArtifactId__-common/src/main/java</ directory >
           < includes >
             < include >**/*.wsdl</ include >
           </ includes >
         </ fileSet >
         < fileSet  filtered = "true"  encoding = "UTF-8" >
           < directory >__rootArtifactId__-common/src/main/resources</ directory >
           < includes >
             < include >**/*.xml</ include >
           </ includes >
         </ fileSet >
         < fileSet  encoding = "UTF-8" >
           < directory >__rootArtifactId__-common/src/META-INF</ directory >
           < includes >
             < include >**/*.MF</ include >
           </ includes >
         </ fileSet >
         < fileSet  filtered = "true"  encoding = "UTF-8" >
           < directory >__rootArtifactId__-common</ directory >
           < includes >
             < include >pom.xml</ include >
           </ includes >
         </ fileSet >
         < fileSet  filtered = "true"  packaged = "true"  encoding = "UTF-8" >
           < directory >__rootArtifactId__-web/src/main/java</ directory >
           < includes >
             < include >**/*.java</ include >
           </ includes >
         </ fileSet >
         < fileSet  filtered = "true"  encoding = "UTF-8" >
           < directory >__rootArtifactId__-web/src/main/webapp</ directory >
           < includes >
             < include >**/*.vm</ include >
             < include >**/*.xml</ include >
             < include >**/*.txt</ include >
           </ includes >
         </ fileSet >
         < fileSet  filtered = "true"  encoding = "UTF-8" >
           < directory >__rootArtifactId__-web/src/main/resources</ directory >
           < includes >
             < include >**/*.xml</ include >
             < include >**/*.properties</ include >
           </ includes >
         </ fileSet >
         < fileSet  encoding = "UTF-8" >
           < directory >__rootArtifactId__-web/src/main/webapp</ directory >
           < includes >
             < include >**/*.jpg</ include >
             < include >**/*.db</ include >
             < include >**/*.MF</ include >
             < include >**/*.png</ include >
             < include >**/*.js</ include >
             < include >**/*.htm</ include >
             < include >**/*.gif</ include >
             < include >**/*.css</ include >
           </ includes >
         </ fileSet >
         < fileSet  filtered = "true"  encoding = "UTF-8" >
           < directory >__rootArtifactId__-web</ directory >
           < includes >
             < include >pom.xml</ include >
           </ includes >
         </ fileSet >
       </ fileSets >
       < modules >
         < module  id = "${rootArtifactId}-aggregator"  dir = "__rootArtifactId__-aggregator"  name = "${rootArtifactId}-aggregator" >
           < fileSets >            
           </ fileSets >
         </ module >
       </ modules >
    </ archetype-descriptor >



    2.文件内容未被替换成占位符

    以上面工程中的quick-start.bat为例,默认情况下此文件中与artfactId同名的字符串就不会被替换成占位符。
    可以手动修改maven/archetype-metadata.xml中的<fileset>,添加属性filtered=true就可以解决这个问题。



    3.原型中没包含空文件夹

    这也是Archetype插件的一个 Bug,无论怎样定义元数据中的<fileset>,Archetype插件都会忽略掉空文件夹。
    在编译原型时插件会输出一些我们可用的变量:


    这些变量在文本文件中使用时要用$,在archetype-metadata.xml中使用时要用__xxx__。以解决这个不拷贝空文件夹的问题为例。

    1
    2
    3
    < fileSet  filtered = "true"  packaged = "false"  encoding = "UTF-8" >
       < directory >__rootArtifactId__-web/src/main/java/__packageInPathFormat__/foo</ directory >
    </ fileSet >

    首先将packaged设置为false,否则foo文件夹里面又会包含一层__packageInPathFormat文件夹结构。
    再执行mvn install后就会发现,编译出的target/generated-sources/archetype/target中的原型包含了空白文件夹。



    4.原型使用方法

    4.1上传原型Jar包

    手动修改好原型项目后,在target/generated-sources/archetype下执行mvn clean install打包出Jar包,就可以上传到Maven的Nexus私服库了。
    通常可以通过Web控制台手动上传和Maven deploy命令上传两种方式,下面以命令方式为例。

    首先要在Maven/conf/settings.xml中的<profile>结点后,添加私服库的验证信息:
    1
    2
    3
    4
    5
    6
    7
    < servers >
         < server >   
             < id >my-snapshot</ id >   
             < username >admin</ username >
             < password >admin123</ password >   
         </ server >
    </ servers >

    执行上传命令即可完成上传:     
    1
    2
    3
    4
    mvn deploy:deploy-file  
    -DgroupId=com.xyz -DartifactId=xyz-archetype -Dversion=1.0-SNAPSHOT  
    -Dpackaging=maven-archetype -Dfile=xyz-archetype-1.0-SNAPSHOT.jar  

    4.2快速生成工程

    首先要在Maven/conf/settings.xml的<repositories>结点中,添加私服库的地址:
    1
    2
    3
    4
    5
    6
    < repository >
         < snapshots  />
         < id >my-snapshot</ id >
         < name >my-snapshot</ name >
    </ repository >

    执行生成命令:
    1
    2
    3
    4
    mvn archetype:generate -B  
    -DarchetypeCatalog=remote -DarchetypeRepository=my-snapshot 
    -DarchetypeGroupId=com.xyz -DarchetypeArtifactId=xyz-archetype -DarchetypeVersion=1.0-SNAPSHOT  
    -DgroupId=com.abc -DartifactId=abc



    参考资料

    1.Maven Archetype元数据配置

    2.如何与Maven原型创建空的文件夹

  • 相关阅读:
    设计模式——创建型设计模式总结(简单工厂、普通工厂、抽象工厂、建造者、原型和单例)
    网易游戏2011招聘笔试题+答案解析
    华为2011上机笔试题2+参考程序
    趋势科技2011校招笔试题+答案解析
    腾讯2012实习生笔试题2+答案解析
    浙商银行2011笔试题+答案解析
    Linux学习笔记(三)——权限管理
    PowerShell在多个文件中检索关键字
    Linux学习笔记(一)——入门
    PowerShell函数调用问题
  • 原文地址:https://www.cnblogs.com/riskyer/p/3398203.html
Copyright © 2011-2022 走看看