1.1 常用的mvn命令
mvn archetype:create 创建 Maven 项目
mvn compile 编译主程序源代码,不会编译test目录的源代码。第一次运行时,会下载相关的依赖包,可能会比较费时
mvn test-compile 编译测试代码,compile之后会生成target文件夹,主程序编译在classes下面,测试程序放在test-classes下
mvn test 运行应用程序中的单元测试
mvn site 生成项目相关信息的网站
mvn clean 清除目标目录中的生成结果
mvn package 依据项目生成 jar 文件,打包之前会进行编译,测试
mvn install在本地 Repository 中安装 jar。
mvn eclipse:eclipse 生成 Eclipse 项目文件及包引用定义
mvn deploy 在整合或者发布环境下执行,将最终版本的包拷贝到远程 的repository,使得其他的开发者或者工程可以共享。
一些高级功能命令
跳过测试类 : -Dmaven.test.skip=true
下载jar包源码: -DdownloadSource=true
下载javadocs: -DdownloadJavadocs=true
2.1 编写POM
就像Make的Makefile、Ant的build.xml一样,Maven项目的核心是pom.xml。POM(Project Object Model),项目对象模型定义了项目的基本信息,用于描述项目如何构建,声明项目依赖,等等。现在先为HelloWorld项目编写一个最简单的pom. xml,
XML头
代码的第一行是XML头,指定了该xml文档的版本和编码方式。
project元素
XML头之后紧接着就是project元素,project是所有pom.xml的根元素,它还声明了一些POM相关的命名空间及xsd元素,虽然这些属性不是必须的,但使用这些属性能够让第三方工具(如IDE中的XMl编辑器)帮助我们快速编辑POM 。
modelVersion元素
根元素下的第一个子元素modelVersion,它指定了当前POM模型的版本,对于Maven 3以及Maven 3来说,它只能是4.0.0。
坐标
这段代码中最重要的是:包含groupId、artifactId和version的三行。这三个元素定义了一个项目基本的坐标,在Maven的世界,任何的jar、pom或者war都是以基于这些基本的坐标进行区分的。
groupId元素
groupId定义了项目属于哪个组,这个组往往和项目所在的组织或公司存在关联。譬如在googlecode上建立了一个名为myapp的项目,那么groupId就应该是com.googlecod.myapp,如果你的公司是mycom,有一个项目为myapp。耶么groupId就应该是com.mycom.myapp。
artifactId元素
artifactId定义了当前Maven项目在组中唯一的ID,我们为这个HelloWord项目定义artifactId为hello-world。在前面的groupld为
com.googlecode.myapp的例子中,你可能会为不同的子项目(模块)分配artifactId,如myapp-util、myapp-domain、myapp-web等。
version元素
顾名思义,version指定了Hello World项目当前的版本0.0.1。SNAPSHOT意为快照,说明该项目还处于开发中,是不稳定的版本。随着项目的展,version会不断更新,如升级为0.0.2、0.0.3、1.0.0等。
name元素
最后一个name元素,声明了一个对于用户更为友好的项目名称,虽然这不是必须的,但还是推荐为每个POM声明name。以方便信息交流。
没有任何实际的Java代码,我们就能够定义一个Maven项目的POM,这体现了Maven的一大优点,它能让项目对象模型最大程度地与实际代码相独立,我们可以称之为解耦,或者正交性。这在很大程度上避免了Java代码和POM代码的相互影响:比如当项目需要升级版本时,只需要修改POM。而不需要更改Java代码;而在POM稳定之后,日常的Java代码开发工作基本不涉及POM的修改。
2.2 编写主代码
项目主代码和测试代码不同,项目的主代码会被打包到最终的构件中如:jar。而测试代码只在运行测试时用到,不会被打包。默认情况下,Maven假设项目主代码位于src/main/java目录,我们遵循Maven的约定,创建该目录,然后在该目录下创建文件org/hebut/test/helloworld/HelloWorld. java
有两点需要注意:首先,在绝大多数情况下,应该把项目主代码放到src/main/java/目录下,而无须额外的配置,Maven会自动搜寻该目录找到项目主代码。其次,该Java类的包名是org.hebut.test.helloworld,这与之前在POM中定义的groupId和artifactld相吻合。一般来说,项目中Java类的包都应该基于项目的groupld和anifactId。这样更加清晰,更加符合逻辑,也方便搜索构件或者Java类。
使用的clean命令告诉Maven清理输出目录target/,compile告诉Maven编译项目主代码,从输出中看到Maven首先执行了clean:clean任务,删除target/目录。默认情况下,Maven构建的所有输出都在target/目录中;接着执行resources:resources任务,未定义项目资源,暂且略过;
最后执行compiler:compile任务,将项目主代码编译至target/classes目录,编译好的类为:
org/hebut/test/helloworld/HelloWorld.Class
上文提到的clean:clean、resources:resources和compiler:compile对应了一些Maven插件及插件目标,比如clean:clean是clean插件的clean目标,compiler:compile是compiler插件的compile目。
至此,Maven在没有任何额外的配置的情况下就执行了项目的清理和编译任务。接下来,编写一些单元测试代码并让Maven执行自动化测试。
2.3 编写测试代码
为了使项目结构保持清晰,主代码与测试代码应陔分别位于独立的目录中。正如上面所述,Maven项目中默认的主代码目录是src/main/java。对应地,Maven项目中默认的测试代码目录是src/test/java
dependencies元素
代码中添加了dependencies元素,该元素下可以包含多个dependency元素以声明项目的依赖。
dependency元素
dependency元素用以声明项目的依赖,这里添加了一个依赖groupId是junit,artifactld是junit,version是4.7。前面提到groupId、artifactId和versIon是任何一个Maven项目最基本的坐标。JUnit也不例外,有了这段声明Maven就能够自动下载junit-4.7.jar。
scope元素
上述POM代码中还有一个值为test的元素scope,scope为依赖范围,若依赖范围为test则表示该依赖只对测试有效。换句话说,测试代码中的import JUnit代码是没有问题的,但是如果在主代码中用import Junit代码,就会造成编译错误。如果不声明依赖范围,那么默认值就是compile,表示该依赖对主代码和测试代码都有效。
默认Maven生成的JAR包只包含了编译生成的.class文件和项目资源文件,而要得到一个可以直接在命令行通过java命令运行的JAR文件,还要满足两个条件
■ JAR包中的/META-INF/MANIFEST.MF元数据文件必须包含Main-Class信息。
■ 项目所有的依赖都必须在Classpath中。
三、使用Archetype生成项目骨架
3.1 Maven 项目约定
HelloWorld项目中有一些Maven的约定:在项目的根目录中放置pom.xml,在src/main/java目录中放置项目的主代码,在src/test/java中放置项目的测试代码。我们称这些基本的目录结构和pom. xml文件内容称为项目的骨架
3.2 Maven Archetype
当第一次创建项目骨架的时候,你还会饶有兴趣地去体会这些默认约定背后的思想,第二次,第三次,你也许还会满意自己的熟练程度,但第四、第五次做同样的事情,你可能就会恼火了。为此Maven提供了Archetype以帮助我们快速勾勒出项目骨架。还是以Hello World为例,我们使用maven archetype来创建该项目的骨架,离开当前的Maven项目目录。
如果是Maven 3简单地运行:
mvn archetype:generate
如果是Maven 2最好运行如下命令:
mvn org.apache.maven.plugins:maven-archetype-plugin:2.0-alpha-5:generate
m2eclipse是Eclipse中的一款Maven插件
spark-submit 错误: ava.lang.ClassNotFoundException: WordCount
跟package name有关
# ./spark-submit –class spark.wordcount.WordCount /opt/spark-wordcount-in-scala.jar
–class后接的格式应该是packageName.objectName。