Contents

之前一直在一些导入的开源工程里编写一些Java代码,所以不怎么遇到依赖问题,最近学习Hadoop,由于安装的是2.4.0版本,在编写hadoop、hbase相关程序的时候,遇到一些依赖问题难以解决,网上搜索结果无论英文还是中文一般都是hadoop 1.x的版本,但是1.x和2.x的包结构根本不一样,尝试了很久手动搜索然后一个一个jar包导入的方式,最后还是提示有问题,这时候我想到了maven工具,虽然一直没有真正使用过,但是知道它在管理依赖方面有很大的优势,所以这两天粗略学习了一下。

  学习一个东西最好的(最适合我的)方式,还是去official site看 getting started 之类的tutorial, 在看过30分钟的入门教程之后(实质follow完远不止30分钟),对Maven有了一个初步的了解,已经能够使用它来创建工程和导入第三方的Jar包了。

  getting started里提到的都是一些最常见的标签,于是我又尝试阅读了一下两个开源项目的POM文件,试着往自己工程的POM里添加相应的标签,最终终于成功编译了一个hbase的程序,之后又尝试了一些restlet等框架,总体感觉maven在解决依赖关系方面确实非常强大,当然Maven远不止是一个为依赖关系而设计的工具,还需要进一步的学习和体会 。

在开始之前,除上官网教程中生成maven工程的命令:相关的package和jar名都可以修改

1
2
3
4
mvn archetype:generate \
-DarchetypeGroupId=org.apache.maven.archetypes \
-DgroupId=com.mycompany.app \
-DartifactId=my-app

如果不加以下的标签,maven会使用java1.3的版本来编译,for each类的循环等后续版本特性是无法支持的,所以以下标签基本是必加的:使用1.7版本编译

1
2
3
4
5
<properties>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<restlet.version>2.1.4</restlet.version>
</properties>

在build resources resource plugins 下,加入以下标签,可以生成runnable的jar包,即内含依赖的jar文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.mumu.hadoop.HbaseTraining</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>

同样位置,加入以下标签 ,可以将依赖的jar包放到你的${projectHome}/target/dependecy-jar/目录下,这样你就能清楚地知道你用到了哪些Jar包,同时也方便分享给别人。

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
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<archive>
<manifest>
<mainClass>org.mumu.hadoop.HbaseTraining</mainClass>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
<addClasspath>true</addClasspath>
<classpathPrefix>dependency-jars/</classpathPrefix>
</manifest>
<manifestEntries>
<Class-Path>/usr/loca/hadoop/hbase-0.98.2-hadoop2/lib/hbase-protocol-0.98.2-hadoop2.jar</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/dependency-jars/
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>

效果如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
└── target
├── classes
│ ├── log4j.properties
│ └── org
│ └── mumu
│ └── restlet
│ └── App.class
├── dependency-jars
│ ├── commons-fileupload-1.3.1.jar
│ ├── commons-io-2.2.jar
│ ├── junit-3.8.1.jar
│ ├── log4j-1.2.17.jar
│ ├── org.osgi.core-4.0.0.jar
│ ├── org.restlet-2.1.7.jar
│ ├── org.restlet.ext.fileupload-2.1.7.jar
│ ├── slf4j-api-1.7.5.jar
│ └── slf4j-log4j12-1.7.5.jar
├── maven-archiver
│ └── pom.properties
├── RestletTest-1.0-SNAPSHOT.jar

最后,如果maven在编译时提示在远程库中找不到jar包,可能需要添加类似如下的标签

1
2
3
4
5
6
7
<repositories>
<repository>
<id>maven-restlet</id>
<name>Restlet Framework repository</name>
<url>http://maven.restlet.com</url>
</repository>
</repositories>

具体的值,一般搜索网页在给出dependecy时也会给出这个repository,留意一下就好了。

最后需要,简单提一下安装m2eclipse插件的安装。使用maven eclipse:eclipse命令就可以就maven工程生成eclipse可导入的工程,但是eclipse会找不到本地库中的jar文件,所以将会显示错误,安装此插件之后,就可以解决这个问题。

安装的方式和其它插件一样,推荐使用在线安装方式,方便快捷,如果失败,则可能需要设置代理。

步骤:help —> install new software —>add

url 为m2e - http://download.eclipse.org/technology/m2e/releases

Contents