0%

问题描述

明明没有错误的Maven项目,导入到Eclipse之后,项目名的旁边会出现一个叉号。虽然不影响项目的使用,但是,看起来总有一点不爽。

解决办法

单击项目,然后alt+F5,Update Maven Project。大部分的项目,都可以通过这个方法去掉叉号。暂时不懂得原理,随着学习的深入,会懂得的。

下载安装Maven

平时使用的,是Eclipse的Eclipse IDE for Java EE Developers 版本,自带Maven。
但是,想要使用Maven本地安装jar文件,就需要自己安装Maven。

下载地址: http://maven.apache.org/download.cgi

1、解压到自己喜欢的目录(这里小编放到D:\Server路径下)。
2、添加环境变量M2_HOME,值为D:\Server\apache-maven-3.3.3
3、在Path中添加;%M2_HOME%\bin;

打开命令提示符,输入mvn -v,如果能够看到maven版本号,说明安装成功。

Oracle驱动jar包安装

以安装Oracle驱动jar包为例。
由于Oracle授权问题,Maven不提供Oracle JDBC Driver,为了在Maven项目中应用Oracle JDBC driver,必须手动添加到本地仓库。

下载jar包

JDBC、SQLJ、Oracle JPublisher 和通用连接池 (UCP)
JDBC and Universal Connection Pool (UCP)

小编使用的是Oracle11g,下载下来的jar包名为ojdbc14.jar。通过解压缩软件看到,jar包中有一个META-INF/MANIFEST.MF文件。打开这个文件,我们看到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Manifest-Version: 1.0
Specification-Title: Oracle JDBC driver classes for use with JDK14
Sealed: true
Created-By: 1.4.2_08 (Sun Microsystems Inc.)
Implementation-Title: ojdbc14.jar
Specification-Vendor: Oracle Corporation
Specification-Version: Oracle JDBC Driver version - "10.2.0.3.0"
Implementation-Version: Oracle JDBC Driver version - "10.2.0.3.0"
Implementation-Vendor: Oracle Corporation
Implementation-Time: Tue Feb 27 15:23:24 2007

Name: oracle/sql/converter/
Sealed: false

Name: oracle/sql/
Sealed: false

Name: oracle/sql/converter_xcharset/
Sealed: false

等下我们要用到version信息:10.2.0.3.0

阅读全文 »

pom.xml速览

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
<project>  
<modelVersion>4.0.0</modelVersion>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<packaging>...</packaging>
<dependencies>...</dependencies>
<parent>...</parent>
<dependencyManagement>...</dependencyManagement>
<modules>...</modules>
<properties>...</properties>

<build>...</build>
<reporting>...</reporting>

<name>...</name>
<description>...</description>
<url>...</url>
<inceptionYear>...</inceptionYear>
<licenses>...</licenses>
<organization>...</organization>
<developers>...</developers>
<contributors>...</contributors>

<issueManagement>...</issueManagement>
<ciManagement>...</ciManagement>
<mailingLists>...</mailingLists>
<scm>...</scm>
<prerequisites>...</prerequisites>
<repositories>...</repositories>
<pluginRepositories>...</pluginRepositories>
<distributionManagement>...</distributionManagement>
<profiles>...</profiles>
</project>

POM包括了所有的项目信息:

  • groupId:项目或者组织的唯一标志,并且配置时生成的路径也是由此生成,如org.codehaus.mojo生成的相对路径为:/org/codehaus/mojo
  • artifactId:项目的通用名称
  • version:项目的版本
  • packaging:打包的机制,如pom, jar, maven-plugin, ejb, war, ear, rar, par
  • classifier:分类

POM关系

依赖

1
2
3
4
5
6
7
8
9
10
11
<dependencies>  
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.0</version>
<type>jar</type>
<scope>test</scope>
<optional>true</optional>
</dependency>
...
</dependencies>
  • groupId, artifactId, version:描述了依赖的项目唯一标志
  • type:相应的依赖产品包形式,如jar,war
  • scope:用于限制相应的依赖范围,包括以下的几种变量:

compile :默认范围,用于编译
provided:类似于编译,但支持你期待jdk或者容器提供,类似于classpath
runtime:在执行时,需要使用
test:用于test任务时使用
system:需要外在提供相应得元素。通过systemPath来取得

  • systemPath: 仅用于范围为system。提供相应的路径
  • optional: 标注可选,当项目自身也是依赖时。用于连续依赖时使用

独占性外在告诉maven你只包括指定的项目,不包括相关的依赖。此因素主要用于解决版本冲突问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
<dependencies>  
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-embedder</artifactId>
<version>2.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

表示项目maven-embedder需要项目maven-core,但我们不想引用maven-core。

聚合

为了能够使用一条命令就能构建account-email和account-persist两个模块,我们需要建立一个额外的名为account-aggregator的模块,然后通过该模块构建整个项目的所有模块。account-aggregator本身也是个 Maven项目,它的 POM如下

1
2
3
4
5
6
7
8
9
10
11
12
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.juvenxu.mvnbook.account</groupId>
<artifactId>account-aggregator</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging> pom </packaging>
<name>Account Aggregator</name>
<modules>
<module>account-email</module>
<module>account-persist</module>
</modules>
</project>

注意:packaging的类型为pom ,module的值是一个以当前POM为主目录的相对路径。

继承

父模块配置

1
2
3
4
5
6
7
8
9
10
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.juvenxu.mvnbook.account</groupId>
<artifactId> account-parent </artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Account Parent</name>

<dependencyManagement>...</dependencyManagement>
</project>

子模块配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<project>
<modelVersion>4.0.0</modelVersion>

< parent >
<groupId>com.juvenxu.mvnbook.account</groupId>
<artifactId> account-parent </artifactId>
<version>1.0.0-SNAPSHOT</version>
< relativePath >../account-parent/pom.xml</ relativePath>
</ parent >

<artifactId> account-email </artifactId>
<name>Account Email</name>
...
</project>

注意:
1、子模块没有声明groupId和version,这两个属性继承至父模块。但如果子模块有不同与父模块的 groupId、version ,也可指定;
2、不应该继承artifactId,如果groupId ,version,artifactId 完全继承的话会造成坐标冲突;另外即使使用不同的 groupId或version,同样的 artifactId也容易产生混淆。

聚合

使用继承后,parent也必须像子模块一样加入到聚合模块中。也就是在在聚合模块的 pom中加入<module>account-parent</module>。聚合的 POM如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.juvenxu.mvnbook.account</groupId>
<artifactId>account-aggregator</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging> pom </packaging>
<name>Account Aggregator</name>
<modules>
<module>account-email</module>
<module>account-persist</module>
<module> account-parent</module>
</modules>
</project>

可继承的元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
groupId :项目组 ID ,项目坐标的核心元素;
version :项目版本,项目坐标的核心元素;
description :项目的描述信息;
organization :项目的组织信息;
inceptionYear :项目的创始年份;
url :项目的 url 地址
develoers :项目的开发者信息;
contributors :项目的贡献者信息;
distributionManagerment :项目的部署信息;
issueManagement :缺陷跟踪系统信息;
ciManagement :项目的持续继承信息;
scm :项目的版本控制信息;
mailingListserv :项目的邮件列表信息;
properties :自定义的 Maven 属性;
dependencies :项目的依赖配置;
dependencyManagement :醒目的依赖管理配置;
repositories :项目的仓库配置;
build :包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等;
reporting :包括项目的报告输出目录配置、报告插件配置等。

我们知道dependencies是可以被继承的,这个时候我们就想到让我们的发生了共用的依赖元素转移到parent中,这样我们又进一步的优化了配置。可是问题也随之而来,如果有一天我创建了一个新的模块,但是这个模块不需要这些parent的依赖,这时候如何处理?

是的,maven的依赖管理就是来解决这个问题的:dependencyManagement。
从上面的列表中我们发现dependencyManagement也是可以被继承的,这恰恰满足了我们的需要,它既能够让子模块继承到父模块的依赖配置,又能保证子模块依赖使用的灵活性。

dependencyManagement的特性:在dependencyManagement中配置的元素既不会给parent引入依赖,也不会给它的子模块引入依赖,仅仅是它的配置是可继承的。

最佳实践:
这时候我们就可以在父POM中声明这些依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
<properties>
<target.version>2.5.6</target.version>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>your groupId</groupId>
<artifactId>your artifactId</artifactId>
<version>${target.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

子模块的POM继承这些配置:子模块继承这些配置的时候,仍然要声明groupId和artifactId,表示当前配置是继承于父POM的,从而直接使用父POM的版本对应的资源。

1
2
3
4
5
6
<dependencies>
<dependency>
<groupId>your groupId</groupId>
<artifactId>your artifactId</artifactId>
</dependency>
</dependencies>

这个可以有效的避免多个子模块使用依赖版本不一致的情况,有助于降低依赖冲突的几率。

注:只有子模块配置了继承的元素,才会真正的有效,否则maven是不会加载父模块中声明的元素。

pluginManagement和dependencyManagement相类似,它是用来进行插件管理的。

聚合和继承的关系

区别 :
1、对于聚合模块来说,它知道有哪些被聚合的模块,但那些被聚合的模块不知道这个聚合模块的存在。
2、对于继承关系的父POM来说,它不知道有哪些子模块继承与它,但那些子模块都必须知道自己的父 POM是什么。

共同点 :
1.聚合 POM与继承关系中的父POM的packaging都是pom
2.聚合模块与继承关系中的父模块除了 POM之外都没有实际的内容。

注:在现有的实际项目中一个 POM既是聚合POM,又是父 POM,这么做主要是为了方便。

参考文档

Maven POM
http://www.yiibai.com/maven/maven_pom.html

maven核心,pom.xml详解
http://blog.csdn.net/zhuxinhua/article/details/5788546

maven 配置篇 之pom.xml(一)
http://www.iteye.com/topic/41754

史上最全的maven pom.xml文件教程详解
http://blog.csdn.net/yaerfeng/article/details/26448417

Maven聚合与继承
http://chenzhou123520.iteye.com/blog/1582166

Maven详解之聚合与继承
http://blog.csdn.net/wanghantong/article/details/36427411

Maven是什么

Maven这个单词来自于意第绪语,意为知识的积累,最早在Jakata Turbine项目中它开始被用来试图简化构建过程。

Maven是基于项目对象模型(POM,Project Object Model),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具。

Maven能做什么

Maven采用了一种被称之为POM的概念来管理项目,所有的项目配置信息都被定义在一个叫做pom.xml的文件中,通过该文件,Maven可以管理项目的整个声明周期,包括编译,构建,测试,发布,报告等等。目前Apache下绝大多数项目都已经采用Maven进行管理。而Maven本身还支持多种插件,可以方便更灵活的控制项目。

小编使用Maven,最深切的体会是,不用手动导入jar包,写写配置文件就搞定了,真方便!

阅读全文 »

名词解释

SSH:SSH不是一个框架,而是多个框架(Struts+Spring+Hibernate)的集成,是目前较流行的一种Web应用程序开源集成框架,用于构建灵活、易于扩展的多层Web应用程序。

Struts:它通过采用 Java Servlet/JSP 技术,实现了基于JavaEE Web应用的MVC设计模式的应用框架,是MVC经典设计模式中的一个经典产品。

Struts2:它是Struts的下一代产品,是在Struts和WebWork的技术基础上进行了合并的全新的Struts2框架。其全新的Struts2的体系结构与Struts的体系结构差别巨大。Struts2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts2可以理解为WebWork的更新产品。

Spring:简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。

阅读全文 »