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
└── 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 \
-DrepositoryId=my-snapshot -Durl=http://127.0.0.1:8989/nexus/content/repositories/snapshots/
|
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原型创建空的文件夹