关于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原型创建空的文件夹

Maven原型骨架及常见问题的更多相关文章

  1. idea中配置maven的骨架本地下载方式

    由于我们使用maven的骨架创建的时候,maven需要联网进行骨架的下载,如果断网了,则骨架不能正常下载,为了防止这种情况,我们可以配置本地下载,当已经联网下载过一次后,以后每次进行下载都会从本地下载 ...

  2. maven自定义骨架

    Maven 的 archetype 技术,为新建标准化的工程框架提供了方便.为自定义一套工程框架标准,可参考以下步骤操作: 1,创建一个项目的原型 2,在项目根目录执行命令:mvn archetype ...

  3. 【Maven实战技巧】「插件使用专题」Maven-Archetype插件创建自定义maven项目骨架

    技术推荐 自定义Archetype Maven骨架/以当前项目为模板创建maven骨架,可以参考http://maven.apache.org/archetype/maven-archetype-pl ...

  4. Intellj新增maven项目骨架

    我们经常用maven骨架构建项目,本来普通的几个archetype就够用的,但是近来要来时开发liferay项目 相关的项目骨架Intellj IDEA就没有内置,所以就想添加进去,  有两个办法可以 ...

  5. 定制Maven原型生成项目

    1自定义原型 1.1创建原型项目 要定制自己的原型,首先就要创建原型项目来进行定制: mvnarchetype:create -DgroupId=com.cdai.arche -DartifactId ...

  6. Maven - 实例-3-自动创建Maven目录骨架

    archetype插件用于创建符合maven规定的目录骨架 方式一:根据提示设置相关参数 guowli@5CG450158J MINGW64 /d/Anliven-Running/Zen/Eclips ...

  7. Maven项目骨架搭建

    1. 如何使用Maven的archetype快速生成一个新项目 2. Maven之自定义archetype生成项目骨架(一) 3. 使用maven3 创建自定义的archetype 4. 使用mave ...

  8. 创建Maven项目骨架并使用

    1.archetype是什么? archetype 字面意思是 原型.可以理解为archetype相当于一个脚手架/模板,通过这个脚手架/模板我们可以快速的创建出一个项目. 比如下图中的这些就是mav ...

  9. MAVEN 自定义骨架

    1)根据原由的骨架先创建出一个骨架模板,例如创建一个web框架可以先通过命令 mvn archetype:generate -DarchetypeCatalog=internal  创建出一个web的 ...

随机推荐

  1. Codeforces Round #430 B. Gleb And Pizza

    Gleb ordered pizza home. When the courier delivered the pizza, he was very upset, because several pi ...

  2. java版的类似飞秋的局域网在线聊天项目

    原文链接:http://www.cnblogs.com/wangleiblog/articles/5323305.html 转载请注明 最近在弄一个java版的局域网在线聊天项目,功能跟飞秋差不多.p ...

  3. 第三次C语言作业

    (一)改错题 计算f(x)的值:输入实数x,计算并输出下列分段函数f(x)的值,输出时保留1位小数. 输入输出样例1: Enterr x: 10.0 f(10.0) = 0.1 输入输出样例2: En ...

  4. Vue2学习结合bootstrapTable遇到的问题

    Vue2学习 项目中在使用bootstrapTable的时候,在table里面会有操作结合vue使用过程中点击相应的操作不会起作用 解决办法 1.把事件绑定到父元素上即可,但要判断什么样的需要点击,用 ...

  5. sssp-springmvc+spring+spring-data-jpa增删改查

    环境:IDE:eclipse.jdk1.7.mysql5.7.maven 项目结构图 上面目录结构你可以自己创建 搭建框架 首先加入maven依赖包以及相关插件 <dependencies> ...

  6. display:none

    $("#loadimg").css("display",""); <span id="loadimg"  clas ...

  7. 在vue生命周期中及时销毁全局作用的代码

    一.纯客户端中 对于全局的代码,比如定时器等,在 beforeDestroy或 destroyed 生命周期时将其销毁.如果在跳转路由时候,组件销毁了,全局的定时器却没有销毁,这会使得页面产生卡顿. ...

  8. 152. Maximum Product Subarray(中等, 神奇的 swap)

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  9. iOS支付宝,微信,银联支付集成封装(上)

    一.集成支付宝支付 支付宝集成官方教程https://docs.open.alipay.com/204/105295/ 支付宝集成官方demo https://docs.open.alipay.com ...

  10. 疯狂的Django 之深度外键跨表查找之疯狂INNER JOIN

    定义Model: from django.db import models class Moreinfo(models.Model): weight = models.FloatField() hei ...