转载自 zhongwen7710的专栏
作为大数据开发者,特别是开发大数据应用程序的程序员或者框架师,在进行大数据项目开发,或者是研读源代码,的把相应的项目导入到集成开发环境,本文用Maven和eclipse来构建大数据开发框架项目。比如说开发storm项目、Hadoop项目、Spark项目等,本文以构建storm项目为例进行图文解读。
提纲摘要:
第一部分:准备工作
第二部分:Maven原理的理解
第三部分:Maven相关环境的配置和部署
第一部分:准备工作:
EclipseIDE:
Maven压缩包:
Strom源代码包:
Win7操作系统:
http://szcs10138456.iteye.com/blog/1009182
第二部分:Maven原理的理解
Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具。 Maven 除了以程序构建能力为特色之外,还提供高级项目管理工具。由于 Maven 的缺省构建规则有较高的可重用性,所以常常用两三行 Maven 构建脚本就可以构建简单的项目。由于 Maven 的面向项目的方法,许多 Apache Jakarta 项目现在使用 Maven,而且公司项目采用 Maven 的比例在持续增长。
A、POM
项目对象模型(Project ObjectModel,POM)描述项目的各个方面,每个Maven项目都应该有一个pom.xml文件。
通常,pom.xml文件由三个主要部分组成(官方介绍):
l 项目管理部分包括项目的组织、开发人员名单、源代码位置和错误跟踪系统 URL 等信息。
l 项目相关性部分包括关于项目相关性的信息。
l 项目构建和报告部分包含项目构建信息(如源代码目录、单元测试用例目录)和要在构建中生成的报告。
B、坐标
坐标为构件(各种jar包)引入了秩序,世界上任何一个构件都可以使用Maven坐标唯一标识,Maven坐标的元素包括groupId artifactId version packaging classifier,我们在开发项目的时候,也需要定义一个坐标,这是Maven强制要求的。——摘自官方对坐标的介绍
下面借助一个例子来介绍坐标中的各个元素:
groupId :定义当前Maven项目隶属的实际项目
artifactId : 定义当前实际项目中的一个Maven项目(模块)
version : 该元素定义Maven项目当前的版本
packaging :定义Maven项目打包的方式(不定义时,默认为:jar),也可以打包成war,ear等
classifier: 该元素用来帮助定义构建输出的一些附件(如:javadoc、sources等),注意,不能直接定义项目的classfier,因为附属构件不是项目直接默认生成的,而是由附加的插件(常用Maven Assembly Plugin)帮助完成。
坐标最佳实践(案例的详细解析)
groupId的值一般为:com.company.projectName
artifactId的值一般为:projectName_moduleName
version的值一般为:<主版本>.<次版本>.<增量版本>-<限定符>,其中主版本主要表示大型架构变更,次版本主要表示特性的增加,增量版本主要服务于bug修复,而限定符如snapshot、alpha、beta等等是用来表示里程碑。
C、依赖
依赖顾名思义,就是这个项目对其他构建或工程的依赖,配置了依赖就相当于将相应的jar包放到了lib目录下(当然这是狭义的理解)。
根元素project下的dependencies可以包含也或多个denpendency元素,用来声明一个或者多个依赖,每个依赖可以包含的元素有(官方对依赖的介绍):
groupId、artifactId、version:依赖的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,Maven根据坐标才能找到依赖。
type:依赖的类型,对于项目坐标定义的packaging。大部分情况下,该元素不必声明,默认为jar。
scope:依赖范围: compile、test、provided、runtime、system
optional:标记依赖是否可选 true|fals
exclusions:用来排除传递性依赖,大部分依赖声明只包含基本坐标,然而在一些特殊的情况下,其他元素至关重要。
D、仓库
Maven仓库是用来帮助我们存储和管理公共构件(主要是jar包)的地方。在Maven世界中,任何一个依赖、插件或者项目构建的输出,都可以成为构件。
实际上Maven项目不会各自存储其依赖文件,它们只需要声明这些依赖的坐标,在需要的时候(例如:编译项目的时候需要将依赖加入到classpath中),Maven会自动根据坐标找到仓库中的构件,并使用它们。
为了实现重用,项目构建完毕后生成的构件也可以安装或者部署到仓库中,供其他项目使用。运行Maven的时候,Maven所需要的任何构件都是直接从本地仓库获取的。如果本地仓库没有,它会首先尝试从远程仓库下载构件至本地仓库,然后再使用本地仓库的构件。
本地仓库:
Maven安装完成后,会在本地创建一个repository目录,这个目录即为本地仓库。本地仓库的默认路径为:${user.home}/.m2/repository/,也可以自定义本地仓库的位置,修改${user.home}/.m2/settings.xml:
...
...
在执行mvn install命令时,Maven会将项目生成的构建安装到本地仓库,供本地其他构建使用。在执行mvn deploy命令时,Maven会将项目生成的构建发布到远程仓库,供所有能访问该仓库的用户使用。
远程仓库:
原始的Maven安装自带了一个远程仓库——Maven中央仓库,中央仓库的id为central,远程url地址为http://repo1.maven.org/maven2,它关闭了snapshot版本构件下载的支持。
特殊的远程仓库--Maven私服:
通过建立私服,可以降低中央仓库负荷、节省外网带宽、加速Maven构建、自己部署构件等,从而高效地使用Maven。
E、生命周期和插件:
Maven对构建(build)的过程进行了抽象和定义,这个过程被称为构建的生命周期(lifecycle),Maven的生命周期是抽象的,这意味着声明周期本身不做任何实际的工作,在Maven的设计中,实际的任务(如编译源代码)都交由插件来完成。
Maven有三套相互独立的生命周期,而且“相互独立”,这三套生命周期分别是:
l Clean Lifecycle 在进行真正的构建之前进行一些清理工作。
l Default Lifecycle 构建的核心部分,编译,测试,打包,部署等等。
l Site Lifecycle 生成项目报告,站点,发布站点。
生命周期细读参考网址(仅供参考):
http://juvenshun.iteye.com/blog/213959
http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
而每套生命周期都是一组阶段(Phase)组成,各套Lifecycle 的Phase如下:
l Clean Lifecycle
pre-clean 执行一些需要在clean之前完成的工作;
clean 移除所有上一次构建生成的文件;
post-clean 执行一些需要在clean之后立刻完成的工作;
l Site Lifecycle
pre-site 执行一些需要在生成站点文档之前完成的工作;
site 生成项目的站点文档;
post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备;
site-deploy 将生成的站点文档部署到特定的服务器上;
l Default Lifecycle
validate
initialize
generate-sources
process-sources
generate-resources
process-resources 复制并处理资源文件,至目标目录,准备打包;
compile 编译项目的源代码;
process-classes
generate-test-sources
process-test-sources
generate-test-resources
process-test-resources 复制并处理资源文件,至目标测试目录;
test-compile 编译测试源代码;
process-test-classes
test 使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署;
prepare-package
package 接受编译好的代码,打包成可发布的格式,如 JAR ;
pre-integration-test
integration-test
post-integration-test
verify
install 将包安装至本地仓库,以让其它项目依赖;
deploy 将最终的包复制到远程的仓库,以让其它开发人员与项目共享;
这些阶段(Phase)是有顺序的,并且后面的阶段依赖于前面的阶段,用户和Maven最直接的交互方式就是这些生命周期阶段(eg:mvn clean install)。
F、聚合与继承
简单的解释:
n 聚合:一个pom包含多个pom
n 继承:一个pom中的内容被多个pom使用,与Java中的继承类似
G、约定优于配置
约定优于配置的实现是通过超级POM实现的,所有的pom文件都继承自超级POM,在超级POM中定义很多约定。
Maven提倡使用一个共同的标准目录结构,使开发人员能在熟悉了一个Maven工程后,对其他的Maven工程也能清晰了解。这样做也省去了很多设置的麻烦。
Maven标准工程的根目录下就只有src和target两个目录,各文件及目录的定义如下:
详细参数解析:
src 存放项目的源文件
-main 存放主代码
–bin 脚本库
–java java源代码文件
–resources 资源库,会自动复制到classes目录里
–filters 资源过滤文件
–assembly 组件的描述配置(如何打包)
–config 配置文件
–webapp web应用的目录,WEB-INF、css、js等
-test 存放测试代码
–java 单元测试java源代码文件
–resources 测试需要用的资源库
–filters 测试资源过滤库
-site Site(一些文档)
target 存放项目构建后的文件和目录,jar包、war包、编译的class文件等
LICENSE.txt 工程的license文件
README.txt 工程的readme文件
参考网址:http://novawoo.github.io/how-to-use-maven/
Maven项目的创建(有图片)——请参考:http://www.iteye.com/topic/1123225
第三部分:Maven相关环境的配置和部署
1、下载安装maven
到http://maven.apache.org下载一个最新版的,我用的是3.1.1版本,解压后即可,如果需要在命令行运行,还需要设置一些环境变量,环境可以这么配置比如说你的maven目录在H:\apache-maven-3.1.1,那么你的系统环境变量需要这么来配置,类似于java的环境变量,配置MAVEN_HOME即为H:\apache-maven-3.1.1,然后配置PATH,为%MAVEN_HOME%\bin,安装成功后当你在命令行下执行mvn -version后能正确显示当前maven的版本就说明你的maven安装成功了。
出现如下错误信息:
Error occurred during initialization of VM
java/lang/NoClassDefFoundError:java/lang/Object
解决方案:(请查看如下Blog)
http://blog.csdn.net/zhongwen7710/article/details/42028873
2、创建maven项目
首先直接来给大家创建一个maven项目,之后再来细讲。首先进入某个盘比如说d:,建立项目mvn archetype:create -DgroupId=com.travelsky.app-DartifactId=travelsky -DarchetypeArtifactId=maven-archetype-webapp
然后cmd进入刚建好的项目文件夹执行命令mvn package 然后再执行mvn eclipse:eclipse执行完毕之后用eclipse把该项目导入即可。
Maven项目的创建——基于eclipse图形界面操作:http://www.iteye.com/topic/1123225
用命令创建Maven项目,命令详解:
mvnarchetype:generate -DarchetypeGroupId=org.apache.maven.archetypes-DgroupId=org.conan.myhadoop.mr -DartifactId=myHadoop-DpackageName=org.conan.myhadoop.mr -Dversion=1.0-SNAPSHOT-DinteractiveMode=false
进入项目,执行mvn命令
D:\workspace\java>cd myHadoop
D:\workspace\java\myHadoop>mvn cleaninstall
导入项目到eclipse(如上面的右图所示)
我们创建好了一个基本的maven项目,然后导入到eclipse中。 这里我们最好已安装好了Maven的插件。
增加组件依赖,如下图所示:
这里我使用hadoop-1.2.1版本,修改文件:pom.xml
如果我们要增加Spark的依赖,进行如下操作(按上面的格式<红颜色的字体>进行书写)
groupId: org.apache.spark
artifactId:spark-core_2.10
version: 1.2.0
如果我们要增加strom的依赖,进行如下操作(按上面的格式<红颜色的字体>进行书写)
groupId: org.apache.storm
artifactId: storm-core
version: 0.9.3
下载依赖:
mvn clean install
http://blog.csdn.net/zhufeng609/article/details/17333143
http://blog.fens.me/hadoop-maven-eclipse/ 《推荐阅读》
maven命令大全
validate, 验证工程是否正确,所有需要的资源是否可用。
compile, 编译项目的源代码。
test-compile, 编译项目测试代码。
test, 使用已编译的测试代码,测试已编译的源代码。
package, 已发布的格式,如jar,将已编译的源代码打包。
integration-test, 在集成测试可以运行的环境中处理和发布包。
verify, 运行任何检查,验证包是否有效且达到质量标准。
install, 把包安装在本地的repository中,可以被其他工程作为依赖来使用
deploy, 在整合或者发布环境下执行,将最终版本的包拷贝到远程的
repository,使得其他的开发者或者工程可以共享。
generate-sources, 产生应用需要的任何额外的源代码,如xdoclet。
第三部分:pom.xml文件详解
1、理解并修改pom.xml文件,配置该文件并自动添加所需要的依赖包。
POM,即Project ObjectModel,通过pom.xml文件配置Maven2,然后Maven2根据此配置执行。作用类似ant的build.xml文件,功能更强大。该文件用于管理:源代码、配置文件、开发者的信息和角色、问题追踪系统、组织信息、项目授权、项目的url、项目的依赖关系等等。
为了更好地理解mvn命令参数和pom.xml文件的基本内容,详细解析如下:
maven 相关:
pom定义了最小的maven2元素,允许groupId,artifactId,version。所有需要的元素
• groupId:项目或者组织的唯一标志,并且配置时生成的路径也是由此生成,如org.codehaus.mojo生成的相对路径为:/org/codehaus/mojo
• artifactId: 项目的通用名称
• version:项目的版本
• packaging: 打包的机制,如pom, jar, maven-plugin, ejb, war, ear, rar, par
• classifier: 分类
范例:
POM关系:
主要为依赖,继承,合成
依赖关系:
...
• groupId, artifactId, version:描述了依赖的项目唯一标志,可以通过以下方式进行安装:
• 使用以下的命令安装:
• mvn install:install-file –Dfile=non-maven-proj.jar–DgroupId=some.group –DartifactId=non-maven-proj –Dversion=1
• 创建自己的库,并配置,使用deploy:deploy-file
• 设置此依赖范围为system,定义一个系统路径。不提倡。
• type:相应的依赖产品包形式,如jar,war
• scope:用于限制相应的依赖范围,包括以下的几种变量:
• compile :默认范围,用于编译
• provided:类似于编译,但支持你期待jdk或者容器提供,类似于classpath
• runtime:在执行时,需要使用
• test:用于test任务时使用
• system:需要外在提供相应得元素。通过systemPath来取得
• systemPath: 仅用于范围为system。提供相应的路径
• optional: 标注可选,当项目自身也是依赖时。用于连续依赖时使用
独占性
外在告诉maven你只包括指定的项目,不包括相关的依赖。此因素主要用于解决版本冲突问题
表示项目maven-embedder需要项目maven-core,但我们不想引用maven-core
继承关系
另一个强大的变化,maven带来的是项目继承。主要的设置:
定义父项目
packaging 类型,需要pom用于parent和合成多个项目。我们需要增加相应的值给父pom,用于子项目继承。主要的元素如下:
• 依赖型
• 开发者和合作者
• 插件列表
• 报表列表
• 插件执行使用相应的匹配ids
• 插件配置
• 子项目配置
relativePath可以不需要,但是用于指明parent的目录,用于快速查询。
dependencyManagement:
用于父项目配置共同的依赖关系,主要配置依赖包相同因素,如版本,scope。
合成(或者多个模块)
一个项目有多个模块,也叫做多重模块,或者合成项目。 如下的定义:
build 设置
主要用于编译设置,包括两个主要的元素,build和report
build
主要分为两部分,基本元素和扩展元素集合
注意:包括项目build和profile build
基本元素
...
• defaultGoal: 定义默认的目标或者阶段。如install
• directory: 编译输出的目录
• finalName: 生成最后的文件的样式
• filter: 定义过滤,用于替换相应的属性文件,使用maven定义的属性。设置所
有placehold的值
资源(resources)
你项目中需要指定的资源。如spring配置文件,log4j.properties
...
...
...
• resources: resource的列表,用于包括所有的资源
• targetPath: 指定目标路径,用于放置资源,用于build
• filtering: 是否替换资源中的属性placehold
• directory: 资源所在的位置
• includes: 样式,包括那些资源
• excludes: 排除的资源
• testResources: 测试资源列表
插件
在build时,执行的插件,比较有用的部分,如使用jdk 5.0编译等等
...
• extensions: true or false,是否装载插件扩展。默认false
• inherited: true or false,是否此插件配置将会应用于poms,那些继承于此的项目
• configuration: 指定插件配置
• dependencies: 插件需要依赖的包
• executions: 用于配置execution目标,一个插件可以有多个目标。
如下:
说明:
• id:规定execution 的唯一标志
• goals: 表示目标
• phase: 表示阶段,目标将会在什么阶段执行
• inherited: 和上面的元素一样,设置false maven将会拒绝执行继承给子插件
• configuration: 表示此执行的配置属性
插件管理
pluginManagement:插件管理以同样的方式包括插件元素,用于在特定的项目中配置。所有继承于此项目的子项目都能使用。主要定义插件的共同元素
扩展元素集合
主要包括以下的元素:
Directories
用于设置各种目录结构,如下:
...
Extensions
表示需要扩展的插件,必须包括进相应的build路径。
...
...
Reporting
用于在site阶段输出报表。特定的maven 插件能输出相应的定制和配置报表。
Report Sets
用于配置不同的目标,应用于不同的报表
...
http://java.sun.com/j2se/1.5.0/docs/api/
更多的项目信息
name:项目除了artifactId外,可以定义多个名称
description: 项目描述
url: 项目url
inceptionYear:创始年份
Licenses
Organization
配置组织信息
Developers
配置开发者信息
Contributors
环境设置
Issue Management
定义相关的bug跟踪系统,如bugzilla,testtrack,clearQuest等
Continuous Integration Management
连续整合管理,基于triggers或者timings
Mailing Lists
SCM
软件配置管理,如cvs 和svn
以上即为pom文件的具体配置解释。
2、maven有他的私服,也就是nexus 作为maven的中央仓库
向maven中导入非官方的
jar:mvninstall:install-file -Dfile=
-DartifactId=
去下载nexus-oss-webapp-1.7.0-bundle.zip,然后解压缩到任意目录下(如E:\nexus)
下载地址:http://nexus.sonatype.org/downloads/
如果操作系统是windows-x86-32 则进入目录
E:\nexus\nexus-oss-webapp-1.7.0\bin\jsw\windows-x86-32运行nexus.bat在浏览器中输入http://localhost:8081/nexus/index.html
即可进入登录页面默认用户名密码是admin/admin123
接着说pox.xml文件
配置MAVEN使用NEXUS作为镜像仓库,首先找到${home.dir}/.m2/settings.xml
文件 如果没有.m2文件夹的话,说明你没有运行过MVN,请在命令行中输入MVN命
令,首次运行MAVEN后会自动创建.M2文件夹,然后进入MAVEN的安装路径下的
CONF文件夹,把默认settings.xml 拷贝到${home.dir}/.m2下。接着在此文件中填入以下信息:
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
注意:Nexus默认是关闭远程索引下载的,主要是担心会造成对服务器的巨大负担。常用的需要开启的三个仓库分别是Maven Center,Apache Snapshots,Codehaus Snapshots;具体的开启方式(以MavenCenter为例):
左侧窗口点击Repositories,右侧会将所有仓库信息显示出来,选中代理仓库Maven Center,更改Configuration->Download Remote Indexes为true,保存配置后,右击代理仓库MavenCenter然后选择ReIndex,如此即可触发Nexus下载远程的索引文件。
3、Nexus中配置自己的数据仓库,及仓库管理 添加一个新的仓库(以添加host仓库为例)
首先以管理员身份登录Nexus,左边导航栏Views/repositories点击Repositories,这样会在右边新窗口列出所有的已知仓库。
然后点击新窗口左上角的Add按钮,下拉选项中我们选在HostRepositories,这样就打开了一个新增Host数据仓库页面,接下来要做的就是根据自己的需要按照提示填写配置信息,填写完成记得点击save按钮保存。
默认的Local StorageLocation会保存在Nexus安装主目录下的\sonatype-work\nexus\storage路径下,如果需要改动,在OverriddingLocal Storage Location项输入相应的路径即可。因为我们maven中配置的公共仓库组是在public Repostitories组中,所以我们需要把新建的仓库添加至public Repostitories.具体操做如下:
在仓库列表中选中publicRepostitories,Configuration –>Available Repositories下将新建仓库(我们这里的新建仓库名为test)拖拽至Ordered Group Repositories,点击save按钮保存配置。
这部操作的时候你可能会疑惑为什么看不到我刚添加的仓库呢,那是因为nexus没刷新,你可以点击刷新按钮刷新下就可以添加了。
给自己的仓库里面上传自己本地的jar包:
选中仓库,选择ArtifactUpload。Artifact Upload下一共有两个模块:select GAV Defination source 和 select Artifact(s)for Upload,我们首先在select Artifact(s) for Upload 模块下点击selectArtifact(s) for upload按钮上传构件,然后在select GAV Defination source模块填写相关构件配置参数Classifier是用来区分同一版本号的不同版本,如poi-3.0-FINAL.jar,FINAL就是它的Classifier.另外Nexus对构件命名校验很严格,一般规则是“构建名+版本号[+Classifier].构建类型” ,上传时的相关参数填写和Maven的pom.xml配置依赖稍微不匹配就可能导致取不到构件。这点一定要注意。
完成保存之后,一定要记得重建索引不然是不会被发现的。