2014/09/22更新,加入了jacoco
2015/07/20更新,jarjar-maven-plugin换成maven-shade-plugin
mybatis的文档挺不错的,最近有兴趣看了一下mybatis的工程,发现它的文档(站点)是通过maven的插件自动生成的。所以我们借巨人的肩膀,不妨分析一下他是如何做到自动生成站点的。
首先要注意的是,要在本地编译mybatis的话,需要2个工程
parent
mybatis-3
本文写作时,最新版本为3.3.0-SNAPSHOT。本文就针对这个版本来分析一下如何生成站点。
1. 运行效果
先不说理论,最好的学习方法就是先运行,然后看效果。
2个工程分别git clone下来以后执行mvn clean install即可。然后会发现target目录下有个site目录,里面就是生成的站点了。浏览一下,有自己写的文档,还有各种报表。
2. maven-site-plugin
这个便是做到生成站点的maven插件了。要注意的是插件的版本是定义在parent中的。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.4</version> <!-- 3.3 works wrong with fluido skin 1.3.x -->
<configuration>
<locales>en,es,ja,fr,zh_CN,ko</locales>
</configuration>
<executions>
<execution>
<id>attach-descriptor</id>
<goals>
<goal>attach-descriptor</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.github.stephenc.wagon</groupId>
<artifactId>wagon-gitsite</artifactId>
<version>0.4.1</version>
</dependency>
<!-- Fluido here only for version update checks on site page -->
<dependency>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
</plugin>
2.1 支持多国语言,执行mvn site后target/site目录下多种语言的站点都生成了。
2.2 采用了maven-site-plugin3.4,说3.3对fluido皮肤有bug
2.3 attach-descriptor 将站点描述符(site.xml)加入到要安装和部署的文件列表中。
2.3.1 站点描述符
是用来自定义站点index页面的方法,需要写src/site/site.xml
2.4 wagon-gitsite
wagon的一个实现,用来将文档部署到github上
2.4.1 wagon
wagon是maven用来处理artifact和repository的抽象传输层,支持以下方式的代码传输:
- File
- HTTP -->http client
- HTTP lightweight
- FTP -->commons net
- SSH/SCP -->jsch
- WebDAV -->jackrabbit
- SCM -->maven scm api
2.5 皮肤
该站点列举了目前可用的5种皮肤
2.5.1 maven-fluido-skin
采用了Twitter Bootstrap的css作为皮肤,使得站点看上去非常的新潮漂亮。
有一点令我不解的是文档上写了要在site.xml中定义skin元素才能运用皮肤,但是mybatis没有这样做,只是如前面的xml里定义了dependency,就可以用这个皮肤了。
2.5.2 其他皮肤资料
http://docs.codehaus.org/display/MAVENUSER/Maven+Skins
这个网址列举了一些皮肤实现,可用来参考激发创作灵感。
2.6 站点文档采用了xdoc格式书写,通过maven-site-plugin可以文档自动转为网站,而maven-pdf-plugin则将文档生成为pdf格式
3. maven-pdf-plugin
执行mvn pdf:pdf以后会在target/pdf目录下生成文档的pdf版本。
这个插件默认是使用fop来生成pdf的,同时也支持itext来生成pdf。
可以定义src/site/pdf.xml,指定要包含哪些文件。
4. doxia
doxia是一个内容生成框架,可以将各种格式的文档生成为另一种格式
比如mybatis里文档时用xdoc格式写的,结果可以输出为html或pdf格式。
目前doxia支持的文档写作格式见如下网址,大概有10来种。
http://maven.apache.org/doxia/references/index.html
APT, Confluence, Simplified DocBook, Markdown, FML, FO, iText, LaTeX, RTF, TWiki, XDoc, XHTML
另外还有一个eclipse插件,可以可视化的书写文档
http://maven.apache.org/doxia/doxia-ide/eclipse/
5. 打包插件
功能是打包成uber-jar。所谓的uber-jar,就是一个fat jar,包含了所有的第三方类库的class文件。之所以需要这样做,是用来将第三方的jar包(javaassist, ognl)一同打入到mybatis里用的。其中一个考虑点是避免不同版本的javassist出现jar包冲突问题。(这里打个比方,比如mybatis用了javassist 1,而客户用了javassist 2,那就jar包冲突了。)mybatis将javassist等重新换个包名打包就可以避免jar包冲突问题了。
mybatis3.3之前采用jarjar-maven-plugin,而之后换成了maven-shade-plugin
5.1 jarjar-maven-plugin
http://sonatype.github.io/jarjar-maven-plugin/
https://github.com/sonatype/jarjar-maven-plugin
https://code.google.com/p/jarjar/
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>jarjar-maven-plugin</artifactId>
<configuration>
<input>{classes}</input>
<input>{test-classes}</input>
<includes>
<include>ognl:ognl</include>
<include>org.javassist:javassist</include>
</includes>
<rules>
<rule>
<pattern>ognl.**</pattern>
<result>org.apache.ibatis.ognl.@1</result>
</rule>
<rule>
<pattern>javassist.**</pattern>
<result>org.apache.ibatis.javassist.@1</result>
</rule>
<keep>
<pattern>org.apache.ibatis.**</pattern>
</keep>
</rules>
<overwrite>true</overwrite>
</configuration>
<executions>
<execution>
<id>jarjar-classes</id>
<phase>process-test-classes</phase>
<goals>
<goal>jarjar</goal>
</goals>
<configuration>
<input>{classes}</input>
</configuration>
</execution>
<execution>
<id>jarjar-test-classes</id>
<phase>process-test-classes</phase>
<goals>
<goal>jarjar</goal>
</goals>
<configuration>
<input>{test-classes}</input>
</configuration>
</execution>
</executions>
</plugin>
mvn jarjar:jarjar
执行 mvn site以后在target/jarjar目录下有
hull-classes
hull-test-classes
uber-classes --> 可以用压缩软件打开,其中打包了javaassist, ognl
uber-test-classes
5.2 maven-shade-plugin
这个是新版的mybatis采用的插件,配置如下
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<artifactSet>
<includes>
<include>org.mybatis:mybatis</include>
<include>ognl:ognl</include>
<include>org.javassist:javassist</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>ognl</pattern>
<shadedPattern>org.apache.ibatis.ognl</shadedPattern>
</relocation>
<relocation>
<pattern>javassist</pattern>
<shadedPattern>org.apache.ibatis.javassist</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
6. 项目信息
如果浏览生成的站点的话,会发现左侧边栏有一栏叫“项目信息”
6.1 Project Dependencies
maven-project-info-reports-plugin
可以查看项目依赖的jar包,license。
Dependency Tree可以清晰的查看各个jar包之间的依赖关系
Project Plugins可以查看用到的plugin
7.项目报表
一堆报表啊,牛叉~~~
7.1 JavaDocs
很简单,用来生成javadoc的
7.1.1 maven-javadoc-plugin/
javadoc插件,没杀好说的。
7.1.2 doclava
一个新的javadoc的皮肤,使得报表看起来新颖,漂亮。
使用范例如下
<doclet>com.google.doclava.Doclava</doclet>
<docletArtifact>
<groupId>com.google.doclava</groupId>
<artifactId>doclava</artifactId>
<version>1.0.6</version>
</docletArtifact>
7.1.3 关于doclet
http://www.oracle.com/technetwork/java/javase/documentation/index-jsp-135444.html
http://docs.oracle.com/javase/1.5.0/docs/guide/javadoc/doclet/spec/index.html
7.1.4 另一个doclet是 umlgraph
可用来自动生成类图和序列图。
另外要生成图片,还需要 Graphviz
生成类图的步骤:
1). 下载
2). 环境变量加入 GRAPHVIZ_HOME=F:\down\graphviz-2.38\release
3).将%GRAPHVIZ_HOME%/bin加入到path
4).修改pom.xml,以使用新的doclet
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<doclet>org.umlgraph.doclet.UmlGraphDoc</doclet>
<docletPath>%GRAPHVIZ_HOME%/bin</docletPath>
<docletArtifact>
<groupId>org.umlgraph</groupId>
<artifactId>doclet</artifactId>
<version>5.1</version>
</docletArtifact>
<additionalparam>-views</additionalparam>
<useStandardDocletOptions>true</useStandardDocletOptions>
</configuration>
</plugin>
5).执行mvn javadoc:javadoc
可以看到
target\site\apidocs\org\apache\ibatis\builder下面多出了一些png图片,这些就是类图了。
下图是生成的一个效果图。
7.2 Source Xref/Test Source Xref
主要方便别人,不用下载源码,可以直接在你的网站上查看源代码和测试代码的。
只要定义如下的 maven-jxr-plugin,这样生成的站点报表里就含有它了。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
<version>2.4</version>
</plugin>
7.3 JDepend
JDepend
jdepend-maven-plugin
用来查看各个包之间的依赖程度,可以作为衡量类的层次结构的设计质量的一个参考。
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jdepend-maven-plugin</artifactId>
<version>2.0</version>
</plugin>
7.4 FindBugs Report
用来分析代码是否有潜藏bug的工具
FindBugs
findbugs-maven-plugin
新的插件已经是3.0了。
随便提一下,FindBugs用BCEL来解析java字节码,用dom4j来处理xml
7.5 Surefire Report
单元测试的统计报表
maven-surefire-report-plugin
主要做的工作是解析surefire-reports下的TEST-*.xml文件,然后将他们渲染成DOXIA格式,进而用来生成站点。
7.6 PMD
PMD
和findbugs一样也是用来查找代码缺陷的。
maven-pmd-plugin
加上这句话以后
<linkXref>true</linkXref>
可以发现点击缺陷可以链接到Xref源码那里。
7.7 CPD
查重复代码的。Copy/Paste Detector (CPD)
http://pmd.sourceforge.net/pmd-5.1.3/cpd.html
7.8 Tag List Report
可以生成TODO,FIXME等信息的报表
taglist-maven-plugin
7.9 Clirr Results
7.9.1 clirr
软件不同版本之间的兼容性我们可能一般会忽略,其实这个也是要考虑的。不然如果你的API频繁改动的话,别人写的老的代码在新的版本下就编译不过了。
Clirr 是用来检查2个版本之间的兼容性的,只要给他2个jar,它就可以dump出变化的API。
7.9.2 clirr-maven-plugin
<clirr.comparisonVersion>3.2.5</clirr.comparisonVersion>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>clirr-maven-plugin</artifactId>
<version>2.6.1</version>
<configuration>
<comparisonVersion>${clirr.comparisonVersion}</comparisonVersion>
<failOnError>false</failOnError>
<failOnWarning>false</failOnWarning>
</configuration>
</plugin>
如上例可看到,比较的是mybatis3.2.5和3.3.0-SNAPSHOT之间的差异
编译的时候,如果本地没有mybatis3.2.5的话,插件会自动去maven仓库去下载3.2.5到本地仓库,然后比较。
7.10 versions-maven-plugin
- Property Updates Report
生成property的变化报表
- Plugin Updates Report
列举了项目用到的plugin,同时提示plugin是否有最新版本
- Dependency Updates Report
列举了项目用到的的dependency,同时提示dependency是否有最新版本
注意点:使用这个插件,pom.xml不能保存为UTF-8 带BOM, 需要存为不带BOM的,否则会出以下错
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-site-plugin:3.4:site (default-site) on project mybatis: Error generating versions-maven-plugin:2.1:property-updates-report: only whitespace content allowed before start tag and not \u9518 (position: START_DOCUMENT seen \u9518... @1:1) -> [Help 1]
7.11 Cobertura Test Coverage
单元测试覆盖率报告
7.11.1 cobertura
是基于jcoverage的单元测试覆盖率报告工具
7.11.2 cobertura-maven-plugin
7.12 Jacoco Coverage
单元测试覆盖率报告,貌似这个现在更高端流行
jacoco
jacoco-maven-plugin
<!-- Introducing jacoco for sonarqube usage initially -->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.2.201409121644</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
8.其他插件
8.1 maven-enforcer-plugin
用来定义一些必须遵守的配置,校验开发环境。比如JDK的版本,Maven的版本,开发环境(Linux,Windows等),依赖jar包的版本等等。
8.2 animal-sniffer-maven-plugin
animal-sniffer
用来检查打包出来的jar包是否兼容老的JDK版本(如JDK5)
名字的由来:动物嗅探器,因为JDK的版本都是用动物名字命名的(tiger等等),所以这个工具就是用来嗅出JDK版本的
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>animal-sniffer-maven-plugin</artifactId>
<version>1.11</version>
<configuration>
<signature>
<groupId>org.codehaus.mojo.signature</groupId>
<artifactId>java16</artifactId>
<version>1.1</version>
</signature>
</configuration>
<executions>
<execution>
<id>check-java-1.6-compat</id>
<phase>process-classes</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
其中的java16表示要兼容JDK6,更多的签名可以参考
http://mojo.codehaus.org/signatures/
8.3 maven-bundle-plugin
maven-bundle-plugin
Bnd
是和OSGI打包有关的
8.4 maven-changes-plugin
用来展示这个版本有哪些变化
<issueManagement>
<system>GitHub Issue Management</system>
<url>https://github.com/mybatis/mybatis-3/issues</url>
</issueManagement>
<configuration>
<issueLinkTemplate>%URL%/issues/%ISSUE%</issueLinkTemplate>
</configuration>
8.5 maven-source-plugin
用来将代码打包到一个jar中
8.6 maven-gpg-plugin
用 GnuPG来给包签名
9. 总结
我们平时做项目一般把代码写完就结束了,但是mybatis不然,非常重视文档。
mybatis用到了很多maven插件来生成文档(站点),是一个可以供大家学习模仿的好sample。
一些常用插件的列表可以参考
http://maven.apache.org/plugins/index.html