Maven入门实战笔记11节[711]

 
Maven入门实战笔记07-私服
 
使用Nexus创建私服
私服:见 Maven入门实战笔记04-仓库 一节中相关内容
 
三种Maven仓库管理软件:
Apache的Archiva
JFrog的Artifactory
Sonatype的Nexus
 
安装Nexus
下载Nexus
http://www.sonatype.org/nexus
Bundle:http://www.sonatype.org/downloads/nexus-latest-bundle.zip
WAR:http://www.sonatype.org/downloads/nexus-latest.war
安装
Bundle方式安装
自带Jetty容器
将下载的压缩包解压到 D:\tools\nexus-2.3.1-01-bundle
nexus-2.3.1-01包:包含Nexus运行所需文件
sonatype-work包:包含Nexus生成的配置文件、日志文件、仓库文件
备份Nexus,默认备份第2个文件
启动:命令行到该目录下 D:\tools\nexus-2.3.1-01-bundle\nexus-2.3.1-01\bin\
运行
Java代码  
nexus install  
Java代码  
nexus install  
 
Java代码  
nexus start  
Java代码  
nexus start  
 
问题:(1)启动问题
Java代码  
wrapper  | OpenSCManager failed - 拒绝访问。 (0x5)  
Java代码  
wrapper  | OpenSCManager failed - 拒绝访问。 (0x5)  
 解决:以管理员身份运行命令行,再执行即可
(2)安装问题
Java代码  
wrapper  | The nexus-webapp service is not installed - 指定的服务未安装。 (0x424)  
Java代码  
wrapper  | The nexus-webapp service is not installed - 指定的服务未安装。 (0x424)  
解决:未安装,先安装,再运行即可
(3)启动问题
Java代码  
wrapper  | Starting the nexus service...  
wrapper  | The nexus service was launched, but failed to start.  
Java代码  
wrapper  | Starting the nexus service...  
wrapper  | The nexus service was launched, but failed to start.  
 到D:\tools\nexus-2.3.1-01-bundle\nexus-2.3.1-01\bin\jsw\conf目录,找到wrapper.conf文件将
Java代码  
wrapper.java.command=java  
Java代码  
wrapper.java.command=java  
修改如下
Java代码  
wrapper.java.command=D:\tools\java\jdk1.7.0\bin\java  
Java代码  
wrapper.java.command=D:\tools\java\jdk1.7.0\bin\java  
不明白:我明明配了java环境,但是只写java就是启动不起来
 
War方式安装
 下载war包,该war包支持主流的Web容器,如Tomcat,Glassfish,Jetty和Resin
 
安装完成后访问:http://localhost:8081/nexus/index.html#welcome,默认端口是8081
登录Nexus
默认管理员用户名和密码admin/admin123
 
Nexus的仓库与仓库组
Nexus包含了各种类型的仓库概念,包括代理仓库、宿主仓库和仓库组
Nexus的内置仓库
 
 
 点击左侧Repositories,界面右边出现仓库列表
仓库有四种类型:group(仓库组)、hosted(宿主)、proxy(代理)和virtual(虚拟)
仓库的格式:Maven1或Maven2
仓库的策略(Policy):表示该仓库是发布(Release)版本仓库还是快照(Snapshot)版本仓库
最后两列为仓库的状态和路径
各个仓库用途:
1.Maven1格式和虚拟类型仓库不提,虚拟类型仓库作用实际上是动态地将仓库内容格式转换,也是为了服务Maven1格式
 
Nexus仓库分类的概念:
根据下图理解宿主仓库
 
仓库Nexus宿主仓库
add->Hosted Repository
 
 
 
 Repository ID:仓库ID、Repository Name:仓库名称、Repository Type:仓库类型
Provider:仓库格式、Repository Polioy:发布版还是快照版
Default Local Storage Location:表示该仓库的默认存储目录,待仓库创建好之后,该值就会成为基于sonatype-work的一个文件
Override Local Storage Location:可以用来 配置自定义仓库目录位置
创建Nexus代理仓库
 
 
多了Remote Storage Location:代表远程仓库的地址,必须输入有效值
Download Remote Indexes 表示是否下载远程仓库的索引
创建Nexus仓库组
在配置界面中,用户可以非常直观地选择Nexus中的仓库,将其聚合成一个虚拟的仓库组
Nexus的索引与构件搜索
为了能够搜索Maven中央库,首先设置Nexus中的Maven Central代理仓库下载远程索引
默认情况这个配置是关闭的
设置:选择中央-->Configuration-->设置Download Remote Indexes为true-->保存
查看状态:左侧Scheduled Tasks
GAV搜索:通过GroupId、ArtifactId和Version信息搜索
类名搜索:搜索包含某个Java类的构件
校验和搜索:直接使用构件的校验和来搜索该构件
以上搜索基于Nexus索引而实现,称为nexus-indexer
为宿主仓库和代理仓库建立索引,在仓库上右击,选择Update Index
配置Maven从Nexus下载构件
在Pom中为Maven配置仓库和插件仓库,只对当前Maven项目有效
通过一次配置让本机所有Maven项目都使用自己的Maven私服,配置settings.xml
但settings.xml并不支持直接配置repositories和pluginRepositories。Maven提供了Profile机制,能让用户将仓库配置放到setting.xml中的Profile中,如:
 
Java代码  
<settings>  
    <profiles>  
        <profile>  
            <id>nexus</id>  
            <repositories>  
                <repository>  
                    <id>nexus</id>  
                    <name>Nexus</name>  
                    <url>http://localhost:8081/nexus/content/groups/public/</url>  
                    <releases>  
                        <enabled>true</enabled>  
                    </releases>  
                    <snapshots>  
                        <enabled>true</enabled>  
                    </snapshots>  
                </repository>  
            </repositories>  
            <pluginRepositories>  
                <pluginRepository>  
                    <id>nexus</id>  
                    <name>Nexus</name>  
                    <url>http://localhost:8081/nexus/content/groups/public</url>  
                </pluginRepository>  
            </pluginRepositories>  
        </profile>  
    </profiles>  
    <activeProfiles>  
        <activeProfile>nexus</activeProfile>  
    </activeProfiles>  
</settings>  
Java代码  
<settings>  
    <profiles>  
        <profile>  
            <id>nexus</id>  
            <repositories>  
                <repository>  
                    <id>nexus</id>  
                    <name>Nexus</name>  
                    <url>http://localhost:8081/nexus/content/groups/public/</url>  
                    <releases>  
                        <enabled>true</enabled>  
                    </releases>  
                    <snapshots>  
                        <enabled>true</enabled>  
                    </snapshots>  
                </repository>  
            </repositories>  
            <pluginRepositories>  
                <pluginRepository>  
                    <id>nexus</id>  
                    <name>Nexus</name>  
                    <url>http://localhost:8081/nexus/content/groups/public</url>  
                </pluginRepository>  
            </pluginRepositories>  
        </profile>  
    </profiles>  
    <activeProfiles>  
        <activeProfile>nexus</activeProfile>  
    </activeProfiles>  
</settings>  
 该配置中使用了一个叫id为nexus的profile
 
activeProfile元素将nexus这个profile激活,这样当执行Maven构建时,激活的profile会将仓库配置应用到项目中去
配置镜像,让Maven只使用私服
 
Java代码  
    <!-- 配置镜像,让Maven只使用私服 -->  
    <mirrors>  
        <mirror>  
            <id>nexus</id>  
            <url>http://localhost:8081/nexus/content/groups/public</url>  
            <mirrorOf>*</mirrorOf>  
        </mirror>  
    </mirrors>  
      
    <profiles>  
        <profile>  
            <id>nexus</id>  
            <repositories>  
                <repository>  
                    <id>nexus</id>  
                    <url>http://central</url>  
                    <releases>  
                        <enabled>true</enabled>  
                    </releases>  
                    <snapshots>  
                        <enabled>true</enabled>  
                    </snapshots>  
                </repository>  
            </repositories>  
            <pluginRepositories>  
                <pluginRepository>  
                    <id>nexus</id>  
                    <url>http://central</url>  
                </pluginRepository>  
            </pluginRepositories>  
        </profile>  
    </profiles>  
    <activeProfiles>  
        <activeProfile>nexus</activeProfile>  
    </activeProfiles>  
</settings>  
Java代码  
    <!-- 配置镜像,让Maven只使用私服 -->  
    <mirrors>  
        <mirror>  
            <id>nexus</id>  
            <url>http://localhost:8081/nexus/content/groups/public</url>  
            <mirrorOf>*</mirrorOf>  
        </mirror>  
    </mirrors>  
      
    <profiles>  
        <profile>  
            <id>nexus</id>  
            <repositories>  
                <repository>  
                    <id>nexus</id>  
                    <url>http://central</url>  
                    <releases>  
                        <enabled>true</enabled>  
                    </releases>  
                    <snapshots>  
                        <enabled>true</enabled>  
                    </snapshots>  
                </repository>  
            </repositories>  
            <pluginRepositories>  
                <pluginRepository>  
                    <id>nexus</id>  
                    <url>http://central</url>  
                </pluginRepository>  
            </pluginRepositories>  
        </profile>  
    </profiles>  
    <activeProfiles>  
        <activeProfile>nexus</activeProfile>  
    </activeProfiles>  
</settings>  
 
仓库与插件仓库配置,它们的id都是central,覆盖了超级POM中央仓库的配置
 
部署构件至Nexus
代理仓库:代理外部公共仓库
宿主仓库:存储组织内部的,或者一些无法从公共仓库中获得的第三方构件
使用Maven部署构件至Nexus每个项目POM的配置
Java代码  
<settings>  
    <!-- 配置Maven部署构件至Nexus -->  
    <distributionManagement>  
        <repository>  
            <id>nexus-releases</id>  
            <name>Nexus Releases Repository</name>  
            <url>http://localhsot:8081/nexus/content/repositories/releases</url>  
        </repository>  
        <snapshotRepository>  
            <id>nexus-snapshots</id>  
            <name>Nexus Snapshots Repository</name>  
            <url>http://localhsot:8081/nexus/content/repositories/snapshots</url>  
        </snapshotRepository>  
    </distributionManagement>  
</project>  
Java代码  
<settings>  
    <!-- 配置Maven部署构件至Nexus -->  
    <distributionManagement>  
        <repository>  
            <id>nexus-releases</id>  
            <name>Nexus Releases Repository</name>  
            <url>http://localhsot:8081/nexus/content/repositories/releases</url>  
        </repository>  
        <snapshotRepository>  
            <id>nexus-snapshots</id>  
            <name>Nexus Snapshots Repository</name>  
            <url>http://localhsot:8081/nexus/content/repositories/snapshots</url>  
        </snapshotRepository>  
    </distributionManagement>  
</project>  
 为部署构件至Nexus配置认证信息,settings.xml的配置
Java代码  
<settings>  
    <!--  为部署构件至Nexus配置认证信息 -->  
    <servers>  
        <server>  
            <id>nexus-releases</id>  
            <username>admin</username>  
            <password>admin123</password>  
        </server>  
        <server>  
            <id>nexus-snapshots</id>  
            <username>admin</username>  
            <password>admin123</password>  
        </server>  
    </servers>  
</settings>  
Java代码  
<settings>  
    <!--  为部署构件至Nexus配置认证信息 -->  
    <servers>  
        <server>  
            <id>nexus-releases</id>  
            <username>admin</username>  
            <password>admin123</password>  
        </server>  
        <server>  
            <id>nexus-snapshots</id>  
            <username>admin</username>  
            <password>admin123</password>  
        </server>  
    </servers>  
</settings>  
 
 
手动部署第三方构件至Nexus上传第三方构件,选择一个宿主仓库如drd party-->在页面正文选择Artifact Upload选项卡
自定义坐标
Nexus的权限管理
Nexus的访问控制模块aNexus是基于权限做访问控制的,服务器的每一个资源都有相应的权限来控制,因此用户执行特定的操作时就必须有必要的权限。管理员必须以角色的方式将权限授予Nexus用户
Nexus预定义了三个用户
admin:该用户拥有对Nexus服务的完全控制,默认密码是admin123
deployment:该用户能够访问Nexus,浏览仓库内容,搜索,并且上传部署构件,但无法对Nexus进行任何配置,默认密码为deployment123
anonymous:该用户对应了所有未登录的匿名用户,它们可以浏览仓库并进行搜索
为项目分配独立的仓库-
Nexus的调度任务
Nexus提供了一系列可配置的调度任务来方便用户管理系统,用户可以设定这些任务的运行方式,例如每天、每周、手动。调度任务会在适当的时候在后台运行
左侧导航栏Scheduled Tasks-->Add
其它私服软件
 
 
----------------------------------------------------------------------------------------
@author Free Coding http://ln-ydc.iteye.com/
settings.rar (749 Bytes)
下载次数: 3
 
 
***********************************************************************************
Maven入门实战笔记08-测试
 
 
测试插件介绍(maven-plugin-plugin)
Maven所做的只是在构建执行到特定生命周期阶段的时候,通过插件来执行JUnit或者TestNG的测试用例。
这一插件就是maven-surefire-plugin,可以称之为测试运行器(Test Runner)
default生命周期test阶段:使用单元测试框架运行测试
 
在默认情况下,maven-surefire-plugin的test目标会自动执行测试源码路径(默认为src/test/java)下所有符一组命名模式的测试类。
**/Test*.java:
**/*Test.java:
**/*TestCase.java:
只要将测试类按上述模式命名,Maven就能自动运行它们,
注意:以Tests结尾的测试类不会得以自动执行
跳过测试
在命令行加参数
 
Java代码  
mvn package -DskipTests  
Java代码  
mvn package -DskipTests  
 也可以在POM配置文件中加参数
Java代码  
<plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-surefire-plugin</artifactId>  
    <version>2.5</version>  
    <configuration>  
        <skipTests>true</skipTests>  
    </configuration>  
</plugin>  
Java代码  
<plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-surefire-plugin</artifactId>  
    <version>2.5</version>  
    <configuration>  
        <skipTests>true</skipTests>  
    </configuration>  
</plugin>  
 Maven也允许跳过编译,但不推荐这么做
 
Java代码  
mvn package -Dmaven.test.skip=true  
Java代码  
mvn package -Dmaven.test.skip=true  
 跳过编译的POM配置
 
 
Java代码  
<!-- 使用UTF-8编码处理资源文件 -->  
<plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-resources-plugin</artifactId>  
    <version>2.5</version>  
    <configuration>  
        <encoding>UTF-8</encoding>  
        <skip>true</skip>  
    </configuration>  
</plugin>  
<!-- 配置测试插件参数 -->  
<plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-surefire-plugin</artifactId>  
    <version>2.5</version>  
    <configuration>  
        <skip>true</skip>  
    </configuration>  
</plugin>  
Java代码  
<!-- 使用UTF-8编码处理资源文件 -->  
<plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-resources-plugin</artifactId>  
    <version>2.5</version>  
    <configuration>  
        <encoding>UTF-8</encoding>  
        <skip>true</skip>  
    </configuration>  
</plugin>  
<!-- 配置测试插件参数 -->  
<plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-surefire-plugin</artifactId>  
    <version>2.5</version>  
    <configuration>  
        <skip>true</skip>  
    </configuration>  
</plugin>  
 手动指定要运行的测试用例
 
 
只运行account-captcha的RandomGeneratorTest
Java代码  
mvn test -Dtest=RandomGeneratorTest -DfailIfNoTests=false  
Java代码  
mvn test -Dtest=RandomGeneratorTest -DfailIfNoTests=false  
 test参数还支持高级赋值方式
Java代码  
mvn test -Dtest=Random*Test  
Java代码  
mvn test -Dtest=Random*Test  
 除星号匹配外,还可以使用逗号指定多个测试用例
Java代码  
mvn test -Dtest=RandomGeneratorTest,AccountCaptchaServiceTest  
Java代码  
mvn test -Dtest=RandomGeneratorTest,AccountCaptchaServiceTest  
 也可以结合使用星号和逗号
Java代码  
mvn test -Dtest=*Test,AccountCaptchaServiceTest  
Java代码  
mvn test -Dtest=*Test,AccountCaptchaServiceTest  
 
test参数必须匹配一个或者多个测试类,如果maven-surefire-plugin找不到任何匹配的测试类,就会报错并导致构建失败,如
Java代码  
mvn test -Dtest  
Java代码  
mvn test -Dtest  
 加上-DfailIfNoTests=false,告诉maven-surefire-plugin即使没有任何测试也不要报错
Java代码  
mvn test -Dtest -DfailIfNoTests=false  
Java代码  
mvn test -Dtest -DfailIfNoTests=false  
包含与排除测试用例
通过额外的配置来自定义包含一些其他测试类,或者排除一些符合默认命名模式的测试类
自动运行以Tests结尾的测试类
Java代码  
<!-- 自动运行以Tests结尾的测试类 -->  
<plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-surefire-plugin</artifactId>  
    <version>2.5</version>  
    <configuration>  
        <includes>  
            <include>**/*Tests.java</include>  
        </includes>  
    </configuration>  
</plugin>  
Java代码  
<!-- 自动运行以Tests结尾的测试类 -->  
<plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-surefire-plugin</artifactId>  
    <version>2.5</version>  
    <configuration>  
        <includes>  
            <include>**/*Tests.java</include>  
        </includes>  
    </configuration>  
</plugin>  
 排除一些符合默认命名模式的测试类
Java代码  
<!-- 排除运行测试类 -->  
<plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-surefire-plugin</artifactId>  
    <version>2.5</version>  
    <configuration>  
        <excludes>  
            <exclude>**/*ServiceTest.java</exclude>  
        </excludes>  
    </configuration>  
</plugin>  
Java代码  
<!-- 排除运行测试类 -->  
<plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-surefire-plugin</artifactId>  
    <version>2.5</version>  
    <configuration>  
        <excludes>  
            <exclude>**/*ServiceTest.java</exclude>  
        </excludes>  
    </configuration>  
</plugin>  
 
测试报告
基本的测试报告
默认情况下,maven-surefire-plugin会在项目的target/surefire-reports目录下生成两种格式的错误报告:
简单文本格式
与JUnit兼容的XML格式
测试覆盖率报告
测试报告覆盖率是衡量项目代码质量的一个重要参考指标
Cobertura是一个优秀的开源测试覆盖率统计工具(http://cobertura.sourceforge.net/),
Maven通过cobertura-maven-plugin与之集成,用户可以使用简单命令为Maven项目生成测试覆盖率报告,如:
Java代码  
mvn cobertura:cobertura  
Java代码  
mvn cobertura:cobertura  
 执行完成后,打开target/site/cobertura/下的index.html文件,就能看到测试覆盖率报告
运行TestNG测试
TestNG是Java除JUnit之外另一个流行的单元测试框架。
NG是Next Generation  
相关资料:
http://testng.org
《Next Generation Java Testing》(Java测试新技术)
首先要删除POM中的JUnit依赖,加入TestNG依赖,如:
Java代码  
<dependency>  
    <groupId>org.testng</groupId>  
    <artifactId>testng</artifactId>  
    <version>6.8</version>  
    <scope>test</scope>  
</dependency>  
Java代码  
<dependency>  
    <groupId>org.testng</groupId>  
    <artifactId>testng</artifactId>  
    <version>6.8</version>  
    <scope>test</scope>  
</dependency>  
 TestNG允许用户使用一个名为testng.xml的文件来配置想要运行的测试集合
可以在account-captcha的项目根目录下创建一个testng.xml文件
Java代码  
<?xml version="1.0" encoding="UTF-8"?>  
<suite name="Suite1" verbose="1">  
    <test name="Regression1">  
        <classes>  
            <class name="com.juvenxu.mvnbook.account.captcha.RandomGeneratorTest"/>  
        </classes>  
    </test>  
</suite>  
Java代码  
<?xml version="1.0" encoding="UTF-8"?>  
<suite name="Suite1" verbose="1">  
    <test name="Regression1">  
        <classes>  
            <class name="com.juvenxu.mvnbook.account.captcha.RandomGeneratorTest"/>  
        </classes>  
    </test>  
</suite>  
 
配置maven-surefire-plugin使用testng.xml
Java代码  
<plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-surefire-plugin</artifactId>  
    <version>2.9</version>  
    <configuration>  
        <suiteXmlFiles>  
            <suiteXmlFile>testng.xml</suiteXmlFile>  
        </suiteXmlFiles>  
    </configuration>  
</plugin>  
Java代码  
<plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-surefire-plugin</artifactId>  
    <version>2.9</version>  
    <configuration>  
        <suiteXmlFiles>  
            <suiteXmlFile>testng.xml</suiteXmlFile>  
        </suiteXmlFiles>  
    </configuration>  
</plugin>  
 
TestNG较JUnit的一大优势在于它支持测试组的概念,如下的注解会将测试方法加入到两个测试组util和medium中
Java代码  
package com.juvenxu.mvnbook.account.captcha;  
  
import static org.junit.Assert.assertFalse;  
  
import java.util.HashSet;  
import java.util.Set;  
  
import org.testng.annotations.Test;  
  
  
public class RandomGeneratorTest {  
    @Test (groups = { "util", "medium" })  
    public void testGetRandomString() throws Exception {  
        Set<String> randoms = new HashSet<String>(100);  
  
        for (int i = 0; i < 100; i++) {  
            String random = RandomGenerator.getRandomString();  
  
            assertFalse(randoms.contains(random));  
  
            randoms.add(random);  
        }  
    }  
}  
Java代码  
package com.juvenxu.mvnbook.account.captcha;  
  
import static org.junit.Assert.assertFalse;  
  
import java.util.HashSet;  
import java.util.Set;  
  
import org.testng.annotations.Test;  
  
  
public class RandomGeneratorTest {  
    @Test (groups = { "util", "medium" })  
    public void testGetRandomString() throws Exception {  
        Set<String> randoms = new HashSet<String>(100);  
  
        for (int i = 0; i < 100; i++) {  
            String random = RandomGenerator.getRandomString();  
  
            assertFalse(randoms.contains(random));  
  
            randoms.add(random);  
        }  
    }  
}  
 由于用户可以自由地标注方法所属的测试组,因此这种机制能让用户在方法级别对测试进行归类
Maven用户可以使用如下配置运行一个或者多个TestNG测试组
 
重用测试代码
mvn package,Maven会将项目的主代码及资源文件打包,将其安装或部署到仓库之后,这些代码就能为他人所用,从而实现Maven项目级别的应用。
默认的打包行为不会包含测试代码的,因此在使用外部依赖的时候,其构件一般不会包含测试代码
在项目内部重用某个模块的测试代码是很常见的需求,可能某个底层模块的测试代码中包含了一些常用的测试工具类,或者一些高质量的测试基类供继承。这个时候,Maven用户就需要通过配置maven-jar-plugin将测试类打包,如:
Java代码  
<plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-jar-plugin</artifactId>  
    <version>2.4</version>  
    <executions>  
        <execution>  
            <goals>  
                <goal>test-jar</goal>  
            </goals>  
        </execution>  
    </executions>  
</plugin>  
Java代码  
<plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-jar-plugin</artifactId>  
    <version>2.4</version>  
    <executions>  
        <execution>  
            <goals>  
                <goal>test-jar</goal>  
            </goals>  
        </execution>  
    </executions>  
</plugin>  
 maven-jar-plugin有两个目标,分别是jar和test-jar,前者通过Maven的内置绑定在default生命周期的package阶段运行,其行为就是对项目主代码进行打包,而后者并没有内置绑定,因此上述插件配置显式声明该目标来打包测试代码
 
上述依赖声明中有一个特殊的元素type,所有测试包构件都使用特殊的test-jar打包类型。需要注意的是,这一类型的依赖同样都使用test依赖范围。
 
 
**********************************************************************
Maven入门实战笔记09-Web应用
 
Web项目的目录结构
基于Java的Web应用,其标准的打包方式是WAR
一个典型的WAR文件有如下目录结构:
 
 
 一个WAR包下至少包含两个子目录:META-INF和WEB-INF。
前者包含了一些打包元数据;后者是WAR包的核心,
WEB-INF下必须包含一个Web资源表述文件web.xml,
它的子目录 classes包含所有该Web项目的类,
而另一个子目录lib则包含所有该Web项目的依赖JAR包
classes和lib目录都会在运行的时候被加入到Classpath中
 
用户必须为Web项目显式指定打包方式为war,如:
Java代码  
<artifactId>account-web</artifactId>  
<packaging>war</packaging>  
<name>Maven Account-Web Project</name>  
Java代码  
<artifactId>account-web</artifactId>  
<packaging>war</packaging>  
<name>Maven Account-Web Project</name>  
 Web项目的类及资源文件:默认位置src/main/java和src/main/resources
 
测试类有测资源文件:默认位置src/test/java和src/test/resources
以上同一般JAR项目
不同:
Web项目还有一个Web资源目录,其默认位置是src/main/webapp
一个典型的Web项目的Maven目录结构如下:
 
 
 
注:finalName该元素用来标识项目生成的主构件的名称,该元素的默认值已在超级POM中设定,值为${project.artifactId}-${project.version},如:account-web-1.0.0-SNAPSHOT.war显然,这样的名称不利于部署,我们需要配置更简洁的名字,如下:
Java代码  
<build>  
    <finalName>account</finalName>  
        ....  
</build>  
Java代码  
<build> 
    <finalName>account</finalName>  
        ....  
</build>  
 
 
使用jetty-maven-plugin进行测试可以用单元测试覆盖的代码就不应该依赖于Web页面测试
页面测试应该仅限于页面的层次,如JSP、CSS、JavaScript的修改,
其它代码修改(如数据访问),请编写单元测试
 
传统的Web测试方法要求我们编译、测试、打包及部署,这往往会消耗数10秒至数分钟的时间,jetty-maven-plugin能够帮助我们节省时间,它能够周期性地检查项目内容,发现变更后自动更新到内置的Jetty Web容器中。
jetty-maven-plutin默认就很好地支持了Maven的项目目录结构,配置如下:
 
Java代码  
<plugin>  
    <groupId>org.mortbay.jetty</groupId>  
    <artifactId>jetty-maven-plugin</artifactId>  
    <version>8.1.9.v20130131</version>  
    <configuration>  
        <scanIntervalSeconds>10</scanIntervalSeconds>  
        <webAppConfig>  
            <contextPath>/test</contextPath>  
        </webAppConfig>  
    </configuration>  
</plugin>  
Java代码  
<plugin>  
    <groupId>org.mortbay.jetty</groupId>  
    <artifactId>jetty-maven-plugin</artifactId>  
    <version>8.1.9.v20130131</version>  
    <configuration>  
        <scanIntervalSeconds>10</scanIntervalSeconds>  
        <webAppConfig>  
            <contextPath>/test</contextPath>  
        </webAppConfig>  
    </configuration>  
</plugin>  
 scanIntervalSeconds:表示该插件扫描项目变更的时间间隔,如果不配置,默认为0,表示不扫描,用户也就失去了自动化热部署的功能
webappConfig元素下的contextPath表示项目部署后的context path。这里值为/text那么用户就可以通过
http://hostname:port/text访问该应用
 
配置一下settings.xml
因为默认情况下,只有org.apache.maven.plugins和org.codehaus.mojo两个groupId下的插件才支持简化的命令行调用,即可以运行mvn help:system,但mvn jetty:run就不行了,因为maven-help-plugin的groupId是org.apache.maven.plugins,而jetty-maven-plugins的groupId是org.mortbay.jetty。为了能在命令行下直接运行mvn jetty:run,用户需要配置settings.xml如下:
Java代码  
<!-- 可以在命令行下直接运行mvn jetty:run -->  
<pluginGroups>  
    <pluginGroup>org.mortbay.jetty</pluginGroup>  
</pluginGroups>  
Java代码  
<!-- 可以在命令行下直接运行mvn jetty:run -->  
<pluginGroups>  
    <pluginGroup>org.mortbay.jetty</pluginGroup>  
</pluginGroups>  
 
 
命令行下启动maven-jetty-plugin
 
Java代码  
mvn jetty:run  
Java代码  
mvn jetty:run  
 jetty-maven-plugin会启动Jetty,并且默认监听本地的8080端口,并将当前项目部署到容器中,同时它还会根据用户配置扫描代码改动。
 
 
如果希望使用其他端口,可以添加jetty.port参数。如:
 
Java代码  
mvn jetty:run -Djetty.port=9999  
Java代码  
mvn jetty:run -Djetty.port=9999  
可通过地址http://localhost:9999/test/测试应用了
 
停止用Ctrl+C
只要不是修改类名、方法名、新增加方法等较大操作,jetty-maven-plugin都能够扫描到变更并正确地将变化更新至Web容器中。
 
参考:jetty插件
 
 
使用Cargo实现自动化部署
Cargo通过cargo-maven2-plugin提供Maven集成,它几乎支持所有的Web容器,如Tomcat、JBoss、Jetty和Glassfish等。
jetty-maven-plugin与cargo-maven2-plugin的功能看起来很相似,但它们的目的不同,
前者主要用来帮助日常的快速开发和测试
后者主要服务于自动化部署
部署至本地Web容器
Cargo支持两种本地部署方式,分别为standalone模式和existing模式。
在standalone模式中,Cargo会从Web容器的安装目录复制一份配置到用户指定的目录,然后在此基础上部署应用,每次重新构建的时候,这个目录都会被清空,所有配置被重新生成。
在existing模式中,用户需要指定现有的Web容器配置目录,然后Cargo会直接使用这些配置并将应用部署到其对应的位置。
使用standalone模式部署应用至本地Web容器
Java代码  
<!-- 使用standalone模式部署应用至本地Web容器 -->  
<plugin>  
    <groupId>org.codehaus.cargo</groupId>  
    <artifactId>cargo-maven2-plugin</artifactId>  
    <version>1.3.3</version>  
    <configuration>  
        <container>  
            <containerId>tomcat6</containerId>  
            <home>D:\tools\web\tomcat6_0_26</home>  
        </container>  
        <configuration>  
            <type>standalone</type>  
            <home>${project.build.directory}/tomcat6x</home>  
        </configuration>  
    </configuration>  
</plugin>  
Java代码  
<!-- 使用standalone模式部署应用至本地Web容器 -->  
<plugin>  
    <groupId>org.codehaus.cargo</groupId>  
    <artifactId>cargo-maven2-plugin</artifactId>  
    <version>1.3.3</version>  
    <configuration>  
        <container>  
            <containerId>tomcat6</containerId>  
            <home>D:\tools\web\tomcat6_0_26</home>  
        </container>  
        <configuration>  
            <type>standalone</type>  
            <home>${project.build.directory}/tomcat6x</home>  
        </configuration>  
    </configuration>  
</plugin>  
 cargo-maven2-plugin的groupId是org.codehaus.cargo,这不属于官方的两插件groupId,因此用户需要将其添加到settings.xml的pluginGroup元素中以方便命令行调用。
Java代码  
<!-- 可以在命令行下直接运行mvn jetty:run 和mvn cargo:start -->  
<pluginGroups>  
    <pluginGroup>org.mortbay.jetty</pluginGroup>  
    <pluginGroup>org.codehaus.cargo</pluginGroup>  
</pluginGroups>  
Java代码  
<!-- 可以在命令行下直接运行mvn jetty:run 和mvn cargo:start -->  
<pluginGroups>  
    <pluginGroup>org.mortbay.jetty</pluginGroup>  
    <pluginGroup>org.codehaus.cargo</pluginGroup>  
</pluginGroups>  
 
configuration下的两个元素
 
type:表示部署的模式
home:表示复制窗口配置到什么位置,这里值为${project.build.directory}/tomcat6x,表示构建输出目录,即target/下的tomcat6x子目录。
container元素下的两个元素
containerId:表示容器的类型
home:表示容器的安装目录
基于该配置,Cargo会从D:\tools\web\tomcat6_0_26目录下复制配置到当前项目的target/tomcat6x/目录下
让Cargo启动Tomcat并部署应用,运行
Java代码  
mvn clean verify cargo:start  
Java代码  
mvn clean verify cargo:start  
 默认情况下,Cargo会让Web容器监听8080端口。可以通过修改Cargo的cargo.servlet.port属性来改变这一配置
更改Cargo的Servlet监听端口:
Java代码  
<!-- 使用standalone模式部署应用至本地Web容器 -->  
<plugin>  
    <groupId>org.codehaus.cargo</groupId>  
    <artifactId>cargo-maven2-plugin</artifactId>  
    <version>1.3.3</version>  
    <configuration>  
        <container>  
            <containerId>tomcat6x</containerId>  
            <home>D:\tools\web\tomcat6_0_26</home>  
        </container>  
        <configuration>  
            <type>standalone</type>  
            <home>${project.build.directory}/tomcat6x</home>  
            <properties>  
                <cargo.servlet.port>8081</cargo.servlet.port>  
            </properties>  
        </configuration>  
    </configuration>  
</plugin>  
Java代码  
<!-- 使用standalone模式部署应用至本地Web容器 -->  
<plugin>  
    <groupId>org.codehaus.cargo</groupId>  
    <artifactId>cargo-maven2-plugin</artifactId>  
    <version>1.3.3</version>  
    <configuration>  
        <container>  
            <containerId>tomcat6x</containerId>  
            <home>D:\tools\web\tomcat6_0_26</home>  
        </container>  
        <configuration>  
            <type>standalone</type>  
            <home>${project.build.directory}/tomcat6x</home>  
            <properties>  
                <cargo.servlet.port>8081</cargo.servlet.port>  
            </properties>  
        </configuration>  
    </configuration>  
</plugin>  
 将应用直接部署到现有的Web容器下,需要配置Cargo使用existing模式
Java代码  
<!-- 使用standalone模式部署应用至本地Web容器  
    configuration-type:standalone   
    configuration-home:${project.build.directory}/tomcat6x  
-->  
<!-- 使用existing模式部署应用至本地Web容器   
    configuration-type:existing  
    configuration-home:D:\tools\web\tomcat6_0_26  
-->  
<plugin>  
    <groupId>org.codehaus.cargo</groupId>  
    <artifactId>cargo-maven2-plugin</artifactId>  
    <version>1.3.3</version>  
    <configuration>  
        <container>  
            <containerId>tomcat6x</containerId>  
            <home>D:\tools\web\tomcat6_0_26</home>  
        </container>  
        <configuration>  
            <type>existing</type>  
            <home>D:\tools\web\tomcat6_0_26</home>  
        </configuration>  
    </configuration>  
</plugin>  
Java代码  
<!-- 使用standalone模式部署应用至本地Web容器  
    configuration-type:standalone   
    configuration-home:${project.build.directory}/tomcat6x  
-->  
<!-- 使用existing模式部署应用至本地Web容器   
    configuration-type:existing  
    configuration-home:D:\tools\web\tomcat6_0_26  
-->  
<plugin>  
    <groupId>org.codehaus.cargo</groupId>  
    <artifactId>cargo-maven2-plugin</artifactId>  
    <version>1.3.3</version>  
    <configuration>  
        <container>  
            <containerId>tomcat6x</containerId>  
            <home>D:\tools\web\tomcat6_0_26</home>  
        </container>  
        <configuration>  
            <type>existing</type>  
            <home>D:\tools\web\tomcat6_0_26</home>  
        </configuration>  
    </configuration>  
</plugin>  
 
使用existing模式部署应用至本地Web容器 基于该配置运行 mvn cargo:start 之后,便能够在Tomcat的webapps子目录看到被部署的Maven项目了。
 
参考:cargo插件
 
部署至远程Web容器
部署应用至远程Web容器
Java代码  
<!-- 部署应用至远程Web容器 -->  
<plugin>  
    <groupId>org.codehaus.cargo</groupId>  
    <artifactId>cargo-maven2-plugin</artifactId>  
    <version>1.3.3</version>  
    <configuration>  
        <container>  
            <containerId>tomcat6x</containerId>  
            <type>remote</type>  
        </container>  
        <configuration>  
            <type>runtime</type>  
            <properties>  
                <cargo.remote.username></cargo.remote.username>  
                <cargo.remote.password></cargo.remote.password>  
                <cargo.remote.manager.url>http://localhost:8080/manager</cargo.remote.manager.url>  
            </properties>  
        </configuration>  
    </configuration>  
</plugin>  
Java代码  
<!-- 部署应用至远程Web容器 -->  
<plugin>  
    <groupId>org.codehaus.cargo</groupId>  
    <artifactId>cargo-maven2-plugin</artifactId>  
    <version>1.3.3</version>  
    <configuration>  
        <container>  
            <containerId>tomcat6x</containerId>  
            <type>remote</type>  
        </container>  
        <configuration>  
            <type>runtime</type>  
            <properties>  
                <cargo.remote.username></cargo.remote.username>  
                <cargo.remote.password></cargo.remote.password>  
                <cargo.remote.manager.url>http://localhost:8080/manager</cargo.remote.manager.url>  
            </properties>  
        </configuration>  
    </configuration>  
</plugin>  
 对于远程部署来说,
container元素的type子元素的值必须为remote,
默认使用installed,并寻找对应的容器安装目录或者安装包
configuration的子元素type的值为runtime,表示即不使用独立的容器配置,也不使用本地现有的容器配置,而是依赖一个已运行的窗口
properties:用来声明一些窗口热部署相关的配置。
例如:Tomcat6就需要提供用户名、密码和管理地址,
让Cargo部署应用
Java代码  
mvn cargo:redeploy  
Java代码  
mvn cargo:redeploy  
 如果容器中已经部署了当前应用,Cargo会先将其卸载,然后再重新部署
 
***********************************************************************************
Maven入门实战笔记10-持续集成
 
持续集成
概念:
持续集成就是快速且高频率地自动构建项目的所有源码,并为项目成员提供丰富的反馈信息。
其中构建包括:编译、测试、审查、打包、部署
持续集成流程:
 
 
 一次完整的集成一般包括6个步骤:
1.持续编译
2.持续数据库集成
3.持续测试
好的单元测试必须是自动化的、可重复执行的、不依赖于环境的,并且能够自我检查的
4.持续审查
Checkstyle和PMD之类的工具发现代码中的坏味道(Bad Smell)
5.持续部署
6.持续反馈
 
硬件设置:集成服务器性能越高越好
源码控制工具、自动化构建工具、自动化测试工具、持续集成软件
优秀的持续集成工具:
开源工具CruiseControl、Hudson
商业的Bamboo和TeamCity
 
Hudson简介
优点:
功能强大、界面易用,与主流构建工具、版本控制系统以及自动化测试框架都能很好集成
灵活的插件扩展框架
安装Hudson
下载:http://hudson-ci.org/  
下载文件为:hudson-3.0.0.war
运行:最简单启动方式为
Java代码  
java -jar hudson-3.0.0.war  
Java代码  
java -jar hudson-3.0.0.war  
 
 
启动后,访问 http://localhost:8080
停止:Ctrl+C
默认商品为8080,指定端口启动
Java代码  
java -jar hudson-3.0.0.war --httpPort=8082  
Java代码  
java -jar hudson-3.0.0.war --httpPort=8082  
 
 
 也可以把war包部署到各种Web容器中
 
问题:用命令行启动时,遇到下列问题:
 
       Initial setup required. Please go to the Hudson Dashboard and complete the setup.
访问hudson设置插件安装,即可(选择默认安装)
安装个插件费这么长时间。。。最后截个图
 
 
 建议装到本地
 
 
选择Install as Windows Service
 
 
准备Subversion仓库
常见版本控制工具:CVS、Subversion、Git、Mercurial
安装Subversion服务器软件(svnserve) 参考   svn应用笔记
常用命令:
1.查看svnserve安装
Java代码  
svnserve --version  
Java代码  
svnserve --version  
 
 
 
 
2.创建一个Subversion仓库
 
Java代码  
mkdir svn-repos  
  
svnadmin create svn-repos\account  
Java代码  
mkdir svn-repos  
  
svnadmin create svn-repos\account  
 3.导入account项目,导入前,用mvn clean清除项目输出文件
 
 
Java代码  
svn import -m "initial import" . file:///d:/svn/svn-repos/account/trunk  
Java代码  
svn import -m "initial import" . file:///d:/svn/svn-repos/account/trunk  
 
 
 上述命令将当前目录的全部内容提交到Subversion仓库的/account/trunk路径下
 
-m选项表示提交的注释
3.启动svnserve服务
Java代码  
svnserve -d -r svn-repos --listen-host 0.0.0.0  
Java代码  
svnserve -d -r svn-repos --listen-host 0.0.0.0  
-d表示将svnserve服务作为守护进程运行
 
-r表示Subversion仓库的位置
--listen-host是为了强制将svnserve绑定到IPv4地址(有些系统,svnserve会默认绑定IPv6,当Hudson使用IPv4地址访问Subversion仓库的时候就会失败)
疑问:这个命令没有指定启动哪个库,若在svn-repos下有多个库的话,是启动哪个呢?
直接用这个命令,就明白了
Java代码  
svnserve -d -r d://svn/svn-repos/account --listen-host 0.0.0.0  
Java代码  
svnserve -d -r d://svn/svn-repos/account --listen-host 0.0.0.0  
 
 
4.检查Subversion仓库内容
 
Java代码  
svn list svn://localhost/account/trunk  
Java代码  
svn list svn://localhost/account/trunk  
 
 
 
 
Hudson的基本系统设置a在创建Hudson持续集成任务之前,用户需要对Hudson系统做一些基本的配置,包括JDK安装位置和Maven安装等在内的重要信息都 必须首先配置正确。
左侧“系统管理”--->右侧“系统设置”
1.配置JDK
Name(别名)
JAVA_HOME
2.配置Maven
Name
MAVEN_HOME
3.配置MAVEN_OPTS环境变量
参考  Maven入门实战笔记01  -Xms128m -Xmx512m
最后,点击页面正文的Save按钮保存系统设置
 
创建Hudson任务
创建Hudson任务来集成Maven项目
左边“新建任务”--->填写任务的名称及类型
 
 
 对于一般Maven项目可选择
    构建一个自由风格的软件项目
    构建一个Maven 2/3 (Legacy)项目
这两项,前者不公支持Maven项目,还支持其他类型的构建工具,如Ant、Shell。
对于Maven用户来说,两者最大的不同在于前者需要用户进行多一点的配置,而后者会使用Hduson自带的Maven,且从项目的POM中获取中够的信息以免去一些配置。推荐free-style
 
Hudson任务的基本配置
1.名称和描述,当任务比较多的时候,简洁而有意义的名称及描述就十分重要
2.Discard Old Builds:该选项配置如何抛弃旧的构建
Hudson每次构建相关的文件都会保存下来,将会渐渐耗光磁盘空间,为此Hudson提供两种方式供选择:
Days to keep builds:如果其值为非空的N,就留N天之内的构建文件
Max # of builds to keep:如果#为非空,就公保留最多#个最近构建的相关文件
 
 上图所示配置表示最多保留10个最近的构建
3.如果有多个JDK,这里还需选择JDK版本
 
Hudson任务的源码仓库配置
在项目配置页面的Source Code Management部分,选择 Subversion,输入Subversion仓库地址 ,一般来说,其他选项保留默认值即可,如图:
 
 
 如果Subversion仓库需要认证,Hudson会提示用户输入认证信息:
 
 
 
Hudson任务的构建触发配置
在Build Triggers部分配置的是触发构建的方式。
Build after other projects are built:在其它项目构建完成后构建本项目
Bukld periodically:周期性地构建本项目
Poll SCM:周期性地轮询源码仓库,发现有更新的时候构建本项目,推荐选这个
 
既然是轮询,就需要配置轮询的频率,Hudson使用了著名的UNIX任务高度工具Cron(http://en.wikipedia.org/wiki/Cron)所使用的配置方式。这种配置方式使用5个字段表示不同的时间单位(字段之间用空格或制表符分隔)
分 :0-59
时 :0-23
日 :1-31
月 :1-12
星期几 :0-7(0和7都表示星期天)
特殊字符:
*:星号表示匹配范围内所有值
M-N:连字符表示匹配M-N范围内的所有值,如"1-5"
A,B,...,Z:逗号表示匹配多个值,如"0,15,10"
*/X或M-N/X:范围加上斜杠表示匹配范围内能被X整除的值,如“1-10/3”,就等同于“3,6,9”
举例:
(1)****:每分钟
(2)5****:每小时中的第5分钟
(3)*/10****:每隔10分钟
(4)45 10 ** 1-5:每周一到周五的上午10点45分
(5)0,30 *  13 * 5:每月13号的每半个小时,或者每周五的每半个小时
在配置轮询的时候,还可以使用“#”添加注释,此外空白的行会被忽略。
对于一个健康的项目来说,觉见做法是:每隔10分钟轮询代码仓库(*/10 * * * *),如图
 
 
 Hudson任务的构建配置
单击Build中的Add build step下三角按钮,选择Invoke Maven2(legacy)(《Maven实践》书中写的是:Invoke top-level Maven targets),如图:
 
 完成后,单击Save
 
 
监视Hudson任务状态a
Hudson界面,了解各个任务的当前及历史状态,包括整体的列表显示、自定义视图、单个任务的具体信息,如构建日志和测试报告等
全局任务状态  
默认主页显示了当前服务上所有集成任务的状态,如图:
 
 
 
 四部分:导航菜单、、构建队列、构建状态、任务状态
任务状态:
S:任务当前状态;
第一列的球形颜色:
蓝色:任务最近一次的构建是成功的
红色:任务最近一次的构建是失败的
黄色:任务最近一次的构建表成功了,但不稳定(主要是因为有失败的测试)
灰色:任务从未被执行过或者被禁用了
如果图标闪烁,表示任务正在执行一次构建
W:天气
第二列,使用天气图标表示任务长期的一个状态
万里晴空:>80%成功
稍有乌云:60%-80%成功
乌云密布:40%-60%成功
阴雨绵绵:20%-40%成功
电闪雷鸣:<20%成功
自定义任务视图
用户可以单击默认视图All旁边的加号(+)以添加一个自定义视图
单个任务状态a
Maven项目测试报告
为了显示项目的测试结果信息,需要一些额外的配置。
maven-surefire-plugin会在项目的tqrget/surefire-reports目录下生成与JUnit兼容的XML格式测试报告,Hudson能够基于这种格式的文件生成图形化的测试报告。
 
为Hudson任务配置测试报告:
用户可以配置一个Hudson,在配置页面的Post-build Action部分选择Publish JUnit test result report选项,并且将Test report XMLs赋值为
**/target/surefire-reports/TEST-*.xml
该表达式表示匹配任意目录下target/surefire-reports/子目录中以Test-开头的XML文件,这也匹配所有maven-surefire-plugin生成的XML格式报告文件
有了上述配置后,就能在任务状态页面中看到最新的测试结果与测试结果趋势
 
配置构建命令忽略测试:
将Maven构建命令以改为:clean deploy -Dmaven.test.failure.ignore
这样失败的测试就不会导致构建失败
这种配置方式能够帮助用户区分失败的构建与不稳定的构建
 
 
Hudson用户管理
Subversion仓库,默认该仓库是匿名可读的,认证用户可写,
现在关闭匿名可读权限,同时添加一些用户。具体参考《Subversion与版本控制》
编辑Subersion仓库下的conf/senserve.conf文件中的[general]小节,如下:
 
Java代码  
[general]  
# anon-access = read  
# auth-access = write  
password-db = passwd  
Java代码  
[general]  
# anon-access = read  
# auth-access = write  
password-db = passwd  
anon-access = none:表示匿名用户没有任何权限
 
auth-access = write:表示经认证用户拥有读写权限
password-db = passwd:表示存储用户信息的数据位于同级目录下的passwd文件中
编辑conf/passwd文件如下:
 
Java代码  
[users]  
admin = admin123  
yangdc = yangdc  
Java代码  
[users]  
admin = admin123  
yangdc = yangdc  
 这里为仓库配置了三个用户,等号左边是用户名,右边是密码
简单的Subversion仓库用户权限配置
用svn命令提交
Java代码  
svn commit -m "add developers config" --username yangdc --password yangdc  
Java代码  
svn commit -m "add developers config" --username yangdc --password yangdc  
 
 
 Hudson得到这些更改并触发集成任务之后,相关的Subversion用户信息就已经被Hudson存储起来了,单击Hudson页面左侧的用户,就可看到相关的用户信息。
点击配置,还可添加用户邮箱
 
 
邮件反馈
为Hudson配置邮件服务器信息。系统设置-->E-mail Notification部分
SMTP
Default user e-mail suffix
System Admin E-mail Address
Hudson URL
SMTP Authentication
 
关于SMTP设置,163邮箱的:
收件服务器设置
IMAP收件服务器地址:imap.163.com 安全:开(SSL/TLS) 端口号:993
126邮箱的IMAP服务器地址:imap.126.com ,
yeah邮箱的IMAP服务器地址:imap.yeah.net,其余部分与163一致;
若安全选择关闭,请将端口号改为 143。 
 
 
 发件服务器设置
SMTP发件服务器地址:smtp.163.com 安全:开(SSL/TLS) 端口号:465 / 994
126邮箱的SMTP服务器地址:smtp.126.com ,
yeah邮箱的SMTP服务器地址:smtp.yeah.net;
若安全选择关闭,请将端口号改为 25。 
 
接下来配置Hudson任务使用邮件反馈,进入任务的配置页面,找到最后Post-build Action小节中 E-mail Notification复选框
问题:什么样的构建触发邮件反馈,邮件会发送给谁?
第一个问题:
(1)失败的构建会触发邮件反馈
(2)成功构建后的一次不稳定构建会触发邮件反馈,不稳定往往是由失败的测试引起的,因此成功后的一次不稳定往往表示有回归性测试失败
(3)失败或不稳定构建后的一次成功构建会触发邮件反馈
(4)用户可以配置是否每次不稳定构建都触发邮件反馈
第二个问题:
可以在 Recipients中配置一个邮件列表(用空格分离),一般来说项目负责人应该在这个列表中,选项 Send separate e-mails to individuals who broke the build  表示是否为所有的不稳定构建触发邮件反馈,如果 不选,只有成功构建后的第一次不稳定构建才会触发邮件反馈。推荐选上    
 
Hudson工作目录
 了解Hudson的工作目录不仅能帮助读者理解Hudson用户界面中的各种特性,更重要的是,读者需要明白怎样为Hudson分配合理的磁盘空间,长期运行的持续集成服务往往会消耗大量的磁盘空间,理解哪些任务对应的哪些文件消耗了多少磁盘空间,对持续集成服务的维护来说是至关重要。
 
默认情况:Hudson使用用户目录下的.hudson/目录作为工作目录
改变该目录,设置环境变量HUDSON_HOME,例如,设置为D:\tools\_data\hudson
一个典型的Hudson工作目录:
*.xml
war
users
userContent
updates
plugins
jobs
 
 
  最重要的就属jobs子目录,
 
 
 
 这里包含了所有Hudson的任务配置、每个任务的工作区、构建历史等信息
每个任务都会包含如config.xml、nextBuildNumber、scm-polling.log等文件,其中config.xml包含了该任务的所有配置
每个任务目录下会包含一个workspace子目录,这就是该任务的工作区,这里有最近一次构建所包含的源代码及相关输出
任务目录下有一个builds子目录,该目录包含了所有Hudson记录的历史构建,每个构建对应了一个目录,目录以发生时间命名
 
************************************************************************************
Maven入门实战笔记11-版本管理
 
目录一览
---------------------------------------
何为版本管理
Maven的版本号定义约定
主干、标签与分支
自动化版本发布
自动化创建分支
GPC签名
 
何为版本管理
区分:版本管理(Version Management)、版本控制(Version Control)
前者,指项目整体版本的演变过程管理,如从1.0-SNAPSHOT到1.0再到
1.1-SNAPSHOT;后者,是指借助版本控制工具追踪代码的每一个变更
 
快照版和发布版之间的转换是版本管理关心的问题之一
发布版本满足的条件:
所有自动化测试应当全部通过
项目没胡配置任何快照版本的依赖
项目没胡配置任何快照版本的插件
项目所包含的代码已经全部提交到版本控制系统中
 
项目发布与标签(Tag)的关系:
版本控制系统记录代码 的每一个变化 ,通常这些变化都被维护在主干(Trunk)中,但是当项目发布的时候 ,开发人员就应该使用标签记录这一特殊的状态。
将项目的快照版本更新至发布版本之后,应当再执行一次Maven构建,以确保项目状态是健康的。然后将这一变更提交到版本控制系统的主干中,接着再为当前主干的状态打上标签。
mvn clean install
svn commit pom.xml -m "prepare to release 1.0"
svn copy -m "tag release 1.0" \
https://localhost/account/trunk \ 
https://localhost/account/tags/1.0
至此,一个版本发布的过程完成了,接下来就是更新发布版本至最新的快照版本。
 
Maven的版本号定义约定
例子:1.3.4-beta-2
表示该项目或产品的第一个重大版本的第三个次要版本的第四次增量版本的beta-2的里程碑。
 
Maven的版本号定义约定:
<主版本>.<次版本>.<增量版本>-<里程碑版本>
主版本:表示项目的重大架构变更
次版本:表示较大范围的功能增加和变化,及Bug修复
增量版本:表示重大Bug的修复
里程碑版本:一个版本的里程碑,与正式版本相比,表示不是非常稳定
 
不是每个版本号都必须拥有这四个部分,前两个一般声明,后两个不一定
注:Maven对于版本号的排序,对于前3个版本是基于数字排序,对于里程碑版本是基于字符串比较排序的
 
主干、标签与分支
主干(trunk):项目开发代码的主体,是从开始直到当前都处于活动的状态
分支(branch):从主干的某个点分离出来的代码拷贝,通常可以在不影响主干的前提下在这里进行重大Bug修复,或者做一些实验性质的开发。如果分支达到了预期的 目的,通常性在这里的变更会被合并(merge)到主干中。
标签(tag):用来标识主干或者分支的某个点的状态,以代表项目的某个稳定状态,这通常就是版本发布时的状态
参考《Subversion与版本控制》
 
自动化版本发布
使用工具Maven RElease Plugin发布项目版本
三个目标:
release:prepare    执行下列操作
    检查项目是否有未提交的代码
    检查项目是否有快照版本依赖
    根据用户的输入将快照版本升级为发布版
    将POM中的SCM信息更新为标签地址
    基于修改后的POM执行Maven构建
    提交POM更新
    基于用户输入为代码打标签
    将代码从发布版升级为新的快照版
    提交POM变更
release:rollback    回退release:prepare所执行的操作,注:该步不会删除release:prepare生成的标签,需手动删除
release:perform    执行版本发布。签出release:prepare生成的标签中的源代码,并在此基础上执行mvn deploy命令打包并部署构件至仓库。
     <!-- 为版本发布配置SCM信息 -->
     <scm >
           <connection> scm:svn:http://localhost /account/trunk</ connection>
           <developerConnection> scm:svn:https://localhost /account/trunk</ developerConnection>
            <url> http://localhost/account/trunk</url >
     </scm >
 
connection:表示一个只读的scm地址
develperConnection:表示可写的scm地址
url:表示可以在浏览器中访问的scm地址
为了让Maven识别,connection和developerConnection必须以scm开头,冒号之后的部分表示版本控制工具类型
该配置只告诉Maven当前版本的位置(主干),而版本发布还要涉及标签操作,因此还需配置Maven Plugin Release Plugin告诉其标签的基础目录
<!-- 配置maven-release-plugin提供标签基础目录 -->
                 <plugin>
                      <groupId> org.apache.maven.plugins</groupId >
                      <artifactId> maven-release-plugin</artifactId>
                      <version> 2.0</version >
                      <configuration>
                           <tagBase> https://localhost/account/tags</tagBase >
                      </configuration>
                 </plugin>
 
 
 
自动化创建分支
a
GPC签名
a
 
原文地址:https://www.cnblogs.com/huapox/p/3251615.html