`
zxc3375
  • 浏览: 135991 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

maven打包编译

 
阅读更多

3.3 编写测试代码
为了使项目结构保持清晰,主代码与测试代码应该分别位于独立的目录中。
Maven项目中默认的主代码目录是src/main/java,对应地,Maven项目中默认的测试代码目录是src/test/java。
因此,在编写测试用例之前,我们先创建该目录。
在Java世界中,由Kent Beck和Erich Gamma建立的JUnit是事实上的单元测试标准。
要使用JUnit,我们首先需要为Hello World项目添加一个JUnit依赖,修改项目的POM如代码清单3-3:
代码清单3-3:为Hello World的POM添加依赖
Java代码

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.juvenxu.mvnbook</groupId>
<artifactId>hello-world</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Maven Hello World Project</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
</project> 

 

代码中添加了dependencies元素,该元素下可以包含多个dependency元素以声明项目的依赖,
这里我们添加了一个依赖——groupId是junit,artifactId是junit,version是4.7。
前面我们提到groupId、artifactId和version是任何一个Maven项目最基本的坐标,
JUnit也不例外,有了这段声明,Maven就能够自动下载junit-4.7.jar。
也许你会问,Maven从哪里下载这个jar呢?在Maven之前,我们可以去JUnit的官网下载分发包。
而现在有了Maven,它会自动访问中央仓库(http://repo1.maven.org/maven2/),下载需要的文件。
读者也可以自己访问该仓库,打开路径junit/junit/4.7/,就能看到junit-4.7.pom和junit-4.7.jar。
上述POM代码中还有一个值为test的元素scope,scope为依赖范围,
若依赖范围为test则表示该依赖只对测试有效,换句话说,测试代码中的import JUnit代码是没有问题的,
但是如果我们在主代码中用import JUnit代码,就会造成编译错误。
如果不声明依赖范围,那么默认值就是compile,表示该依赖对主代码和测试代码都有效。
配置了测试依赖,接着就可以编写测试类,
回顾一下前面的HelloWorld类,现在我们要测试该类的sayHello()方法,
检查其返回值是否为“Hello Maven”。在src/test/java目录下创建文件,
其内容如代码清单3-4:
代码清单3-4:Hello World的测试代码
Java代码

package com.juvenxu.mvnbook.helloworld;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class HelloWorldTest
{
@Test
public void testSayHello()
{
HelloWorld helloWorld = new HelloWorld();

String result = helloWorld.sayHello();

assertEquals( "Hello Maven", result );
}
}

 
一个典型的单元测试包含三个步骤:
一,准备测试类及数据;
二,执行要测试的行为;
三,检查结果。
上述样例中,我们首先初始化了一个要测试的HelloWorld实例,
接着执行该实例的sayHello()方法并保存结果到result变量中,
最后使用JUnit框架的Assert类检查结果是否为我们期望的”Hello Maven”。
在JUnit 3中,约定所有需要执行测试的方法都以test开头,这里我们使用了JUnit 4,
在JUnit 4中,需要执行的测试方法都应该以@Test进行标注。
测试用例编写完毕之后就可以调用Maven执行测试,运行 mvn clean test :
Java代码
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Hello World Project
[INFO] task-segment: [clean, test]
[INFO] ------------------------------------------------------------------------
[INFO] [clean:clean {execution: default-clean}]
[INFO] Deleting directory D:\git-juven\mvnbook\code\hello-world\target
[INFO] [resources:resources {execution: default-resources}]
Downloading: http://repo1.maven.org/maven2/junit/junit/4.7/junit-4.7.pom
1K downloaded (junit-4.7.pom)
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Compiling 1 source file to D: \code\hello-world\target\classes
[INFO] [resources:testResources {execution: default-testResources}]
Downloading: http://repo1.maven.org/maven2/junit/junit/4.7/junit-4.7.jar
226K downloaded (junit-4.7.jar)
[INFO] [compiler:testCompile {execution: default-testCompile}]
[INFO] Compiling 1 source file to D:\ code\hello-world\target\test-classes
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Compilation failure
D:\code\hello-world\src\test\java\com\juvenxu\mvnbook\helloworld\HelloWorldTest.java:[8,5] -source 1.3 中不支持注释
(请使用 -source 5 或更高版本以启用注释)
@Test
[INFO] ------------------------------------------------------------------------
[INFO] For more information, run Maven with the -e switch



不幸的是构建失败了,不过我们先耐心分析一下这段输出(为了本书的简洁,一些不重要的信息我用省略号略去了)。
命令行输入的是mvn clean test,而Maven实际执行的可不止这两个任务,
还有clean:clean、resources:resources、compiler:compile、resources:testResources以及compiler:testCompile。
暂时我们需要了解的是,在Maven执行测试(test)之前,
它会先自动执行项目主资源处理,主代码编译,测试资源处理,测试代码编译等工作,
这是Maven生命周期的一个特性,本书后续章节会详细解释Maven的生命周期。
从输出中我们还看到:Maven从中央仓库下载了junit-4.7.pom和junit-4.7.jar
这两个文件到本地仓库(~/.m2/repository)中,供所有Maven项目使用。
构建在执行compiler:testCompile任务的时候失败了,Maven输出提示我们需要使用-source 5或更高版本以启动注释,
也就是前面提到的JUnit 4的@Test注解。这是Maven初学者常常会遇到的一个问题。
由于历史原因,Maven的核心插件之一compiler插件默认只支持编译Java 1.3,
因此我们需要配置该插件使其支持Java 5,见代码清单3-5:
代码清单3-5:配置maven-compiler-plugin支持Java 5
Java代码

<project>
…
<build>
<plugins>
<plugin>
	<artifactId>maven-compiler-plugin</artifactId>
	<version>3.1</version>
	<configuration></configuration>
</plugin>
</plugins>
</build>
…
</project> 

 

该POM省略了除插件配置以外的其他部分,我们暂且不去关心插件配置的细节,只需要知道compiler插件支持Java 5的编译。
现在再执行mvn clean test,输出如下:
Java代码

[INFO] [compiler:testCompile {execution: default-testCompile}]
[INFO] Compiling 1 source file to D: \code\hello-world\target\test-classes
[INFO] [surefire:test {execution: default-test}]
[INFO] Surefire report directory: D:\code\hello-world\target\surefire-reports
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.juvenxu.mvnbook.helloworld.HelloWorldTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.055 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------


我们看到compiler:testCompile任务执行成功了,测试代码通过编译之后在target/test-classes下生成了二进制文件,
紧接着surefire:test任务运行测试,surefire是Maven世界中负责执行测试的插件,
这里它运行测试用例HelloWorldTest,并且输出测试报告。显然,我们的测试通过了——BUILD SUCCESSFUL。
---------------------------------------
3.4 打包和运行

将项目进行编译、测试之后,下一个重要步骤就是打包(package)。
Hello World的POM中没有指定打包类型,使用默认打包类型jar,
我们可以简单地执行命令 mvn clean package 进行打包,
可以看到如下输出:
Java代码
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] [jar:jar {execution: default-jar}]
[INFO] Building jar: D:\code\hello-world\target\hello-world-1.0-SNAPSHOT.jar
[INFO]
--------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL

类似地,Maven会在打包之前执行编译、测试等操作。
这里我们看到jar:jar任务负责打包,实际上就是jar插件的jar目标将项目主代码打包成一个名为hello-world-1.0-SNAPSHOT.jar的文件,
该文件也位于target/输出目录中,它是根据artifact-version.jar规则进行命名的,
如有需要,我们还可以使用finalName来自定义该文件的名称,这里暂且不展开,本书后面会详细解释。
至此,我们得到了项目的输出,如果有需要的话,就可以复制这个jar文件到其他项目的Classpath中从而使用HelloWorld类。
但是,如何才能让其他的Maven项目直接引用这个jar呢?
我们还需要一个安装的步骤,执行 mvn clean install:
Java代码

[INFO] [jar:jar {execution: default-jar}]
[INFO] Building jar: D: \code\hello-world\target\hello-world-1.0-SNAPSHOT.jar
[INFO] [install:install {execution: default-install}]
[INFO] Installing D:\code\hello-world\target\hello-world-1.0-SNAPSHOT.jar to
C:\Users\juven\.m2\repository\com\juvenxu\mvnbook\hello-world\1.0-SNAPSHOT\hello-world-1.0-SNAPSHOT.jar
[INFO]
------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL

在打包之后,我们又执行了安装任务install:install,
从输出我们看到该任务将项目输出的jar安装到了Maven本地仓库中,
我们可以打开相应的文件夹看到Hello World项目的pom和jar。
之前讲述JUnit的POM及jar的下载的时候,我们说只有构件被下载到本地仓库后,才能由所有Maven项目使用,
这里是同样的道理,只有将Hello World的构件安装到本地仓库之后,其他Maven项目才能使用它。
我们已经将体验了Maven最主要的命令:mvn clean compile、mvn clean test、mvn clean package、mvn clean install。
执行test之前是会先执行compile的,执行package之前是会先执行test的,
而类似地,install之前会执行package。我们可以在任何一个Maven项目中执行这些命令,而且我们已经清楚它们是用来做什么的。

到目前为止,我们还没有运行Hello World项目,不要忘了HelloWorld类可是有一个main方法的。
默认打包生成的jar是不能够直接运行的,因为带有main方法的类信息不会添加到manifest中
(我们可以打开jar文件中的META-INF/MANIFEST.MF文件,将无法看到Main-Class一行)。
为了生成可执行的jar文件,我们需要借助maven-shade-plugin,配置该插件如下:
Java代码

<plugin> 
	<artifactId>maven-shade-plugin</artifactId>
	<version>2.2</version>
	<executions>
		<execution>
			<phase>package</phase>
			<goals>
				<goal>shade</goal>
			</goals>
			<configuration>
				<transformers>
					<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
						<mainClass>com.juvenxu.mvnbook.helloworld.HelloWorld</mainClass> mainclass类
					</transformer>
				</transformers>
			</configuration>
		</execution>
	</executions>
</plugin>

 

plugin元素在POM中的相对位置应该在<project><build><plugins>下面。
我们配置了mainClass为com.juvenxu.mvnbook.helloworld.HelloWorld,项目在打包时会将该信息放到MANIFEST中。
现在执行 mvn clean install ,待构建完成之后打开target/目录,
我们可以看到hello-world-1.0-SNAPSHOT.jar和original-hello-world-1.0-SNAPSHOT.jar,
前者是带有Main-Class信息的可运行jar,后者是原始的jar,
打开hello-world-1.0-SNAPSHOT.jar的META-INF/MANIFEST.MF,可以看到它包含这样一行信息:
Main-Class: com.juvenxu.mvnbook.helloworld.HelloWorld
现在,我们在项目根目录中执行该jar文件:
D: \code\hello-world>java -jar target\hello-world-1.0-SNAPSHOT.jar
Hello Maven
控制台输出为Hello Maven,这正是我们所期望的。
本小节介绍了Hello World项目,侧重点是Maven而非Java代码本身,
介绍了POM、Maven项目结构、以及如何编译、测试、打包,等等。
------------------------------------------------------
3.5 使用Archetype生成项目骨架
Hello World项目中有一些Maven的约定:
在项目的根目录中放置pom.xml,
在src/main/java目录中放置项目的主代码,
在src/test/java中放置项目的测试代码。
我们称这些基本的目录结构和pom.xml文件内容称为项目的骨架,
当你第一次创建项目骨架的时候,你还会饶有兴趣地去体会这些默认约定背后的思想,
第二次,第三次,你也许还会满意自己的熟练程度,但第四、第五次做同样的事情,就会让程序员恼火了,
为此Maven提供了Archetype以帮助我们快速勾勒出项目骨架。
还是以Hello World为例,我们使用maven archetype来创建该项目的骨架,离开当前的Maven项目目录。
如果是Maven 3,简单的运行:
mvn archetype:generate
我们实际上是在运行插件maven-archetype-plugin,
注意冒号的分隔,其格式为 groupId:artifactId:version:goal ,
org.apache.maven.plugins 是maven官方插件的groupId,maven-archetype-plugin
是archetype插件的artifactId,2.0-alpha-5 是目前该插件最新的稳定版,generate是我们要使用的插件目标。
紧接着我们会看到一段长长的输出,有很多可用的archetype供我们选择,
包括著名的Appfuse项目的archetype,JPA项目的archetype等等。
每一个archetype前面都会对应有一个编号,同时命令行会提示一个默认的编号,
其对应的archetype为maven-archetype-quickstart,我们直接回车以选择该archetype,
紧接着Maven会提示我们输入要创建项目的groupId、artifactId、 version、以及包名package,如下输入并确认:
Java代码
Define value for groupId: : com.juvenxu.mvnbook
Define value for artifactId: : hello-world
Define value for version: 1.0-SNAPSHOT: :
Define value for package: com.juvenxu.mvnbook: : com.juvenxu.mvnbook.helloworld
Confirm properties configuration:
groupId: com.juvenxu.mvnbook
artifactId: hello-world
version: 1.0-SNAPSHOT
package: com.juvenxu.mvnbook.helloworld
Y: : Y

Archetype插件将根据我们提供的信息创建项目骨架。
在当前目录下,Archetype插件会创建一个名为hello-world(我们定义的artifactId)的子目录,
从中可以看到项目的基本结构:基本的pom.xml已经被创建,里面包含了必要的信息以及一个junit依赖;
主代码目录src/main/java已经被创建,在该目录下还有一个Java类com.juvenxu.mvnbook.helloworld.App,
注意这里使用到了我们刚才定义的包名,而这个类也仅仅只有一个简单的输出Hello World!的main方法;
测试代码目录src/test/java也被创建好了,并且包含了一个测试用例com.juvenxu.mvnbook.helloworld.AppTest。
Archetype可以帮助我们迅速地构建起项目的骨架,
在前面的例子中,我们完全可以在Archetype生成的骨架的基础上开发Hello World项目以节省我们大量时间。
此外,我们这里仅仅是看到了一个最简单的archetype,
如果你有很多项目拥有类似的自定义项目结构以及配置文件,
你完全可以一劳永逸地开发自己的archetype,然后在这些项目中使用自定义的archetype来快速生成项目骨架

---------------------------------------------------------------------------------------------------

1.7java-maven书籍

Maven实战 许晓斌 (2012-12出版)

分享到:
评论

相关推荐

    maven打包 maven打jar包详细步骤

    本文将详细讲解如何使用Maven来打包一个Java项目,并创建JAR文件。 首先,Maven有三个主要生命周期阶段:`clean`、`default`(也称为`compile`)和`install`。每个阶段包含一系列的阶段(或者称为目标,如`compile`...

    maven已编译包

    5. **插件 (Plugins)**:Maven通过插件执行特定的任务,如编译源代码、运行单元测试、打包项目等。在Maven 2.0.11中,包含了一些基本的插件,如maven-compiler-plugin用于编译,maven-surefire-plugin用于执行测试。...

    Maven打包,指定classes路径

    以上就是关于"Maven打包,指定classes路径"的知识点,主要涉及到Maven的资源配置和插件定制。理解并掌握这些配置可以帮助开发者更高效地管理和构建Java Web应用。同时,记得在实际项目中根据实际情况调整`pom.xml`,...

    maven项目编译jar包

    通过以上步骤,你就可以使用Maven成功地编译和打包一个Java项目为JAR文件。确保你的环境中已经安装了Maven,并且配置了正确的Maven环境变量,然后按照上述方法操作即可。记住,Maven的强大在于它的标准化和自动化,...

    maven打包出错解决办法,亲测绝对可以!

    本篇文章将详细阐述如何解决Maven打包出错的问题,并分享一些关于搭建Maven私服的知识。 一、Maven打包出错常见原因及解决办法 1. **依赖冲突**:当项目中的多个库引用了不同版本的同一个依赖时,可能导致冲突。...

    maven打包使用yui压缩css和js文件

    在命令行中,我们可以通过运行 `mvn clean package` 命令来触发Maven生命周期,这将清理旧的构建产物,编译源代码,并最终打包项目。在这个过程中,YUI Compressor会自动对指定的CSS和JS文件进行压缩。 4. **检查...

    Windows下git拉取/推送,SVN更新/提交,maven自动编译打包,angular打包的bat脚本

    本主题将详细讲解如何利用Git进行拉取与推送,SVN进行更新和提交,Maven实现自动化编译,以及Angular项目的打包发布,这一切都将通过批处理(BAT)脚本来实现,以提高工作效率。 首先,我们来看Git的拉取(pull)和...

    jasperreport maven打包后找不到字体解决方案

    jasperreport 用maven打包后找不到字体解决方案 net.sf.jasperreports.engine.JRRuntimeException: Could not load the following font

    reportng源码(maven编译打包)

    在这个“reportng源码(maven编译打包)”项目中,我们可以看到ReportNG的源代码,它是使用Maven构建系统进行管理的。Maven是一个广泛使用的Java项目管理和集成工具,它帮助开发者自动化构建、依赖管理和项目信息管理...

    Java+IDEA+maven混淆打包

    1. **配置Maven打包**: 在`pom.xml`文件中,我们需要添加`maven-jar-plugin`插件来打包Java项目。以下是一个基本的配置示例: ```xml &lt;groupId&gt;org.apache.maven.plugins &lt;artifactId&gt;maven-jar-plugin ...

    如何提高Maven多模块项目编译速度.docx

    以下是一些优化Maven多模块项目编译速度的策略: 1. **利用多核CPU并行编译**: Maven的 `-T` 参数可以用来指定并发编译的线程数。例如,`-T 4C` 表示使用4个CPU核心进行并行编译,这样能充分利用硬件资源,加快...

    Maven打包实战.zip

    本压缩包文件“Maven打包实战.zip”提供了关于Maven打包的实战教程,配合文章《Maven打包实战》(链接已提供)学习,将有助于深入理解Maven的打包流程。 首先,我们需要理解Maven的生命周期。Maven生命周期包括三个...

    Java+IDEA+Maven混淆打包

    本教程将详细讲解如何在IntelliJ IDEA(IDEA)中利用Maven进行混淆打包,确保代码的安全性并提高可维护性。 首先,让我们了解一下涉及的工具和技术: 1. **Java**: 一种广泛使用的面向对象的编程语言,用于构建跨...

    Maven自动升级版本号并打包上传的脚本

    3. Maven打包: `mvn package`命令会将源代码编译、测试并打包成指定格式(如JAR或WAR)。如果配置了`&lt;build&gt;&lt;finalName&gt;yourArtifactId&lt;/finalName&gt;&lt;/build&gt;`,那么生成的文件名将会是`yourArtifactId-1.0.0-...

    Storm编程实践(安装Maven-使用Maven编译运行代码-mvn 打包)

    Storm 编程实践(安装 Maven-使用 Maven 编译运行代码-mvn 打包) 本文档介绍了 Storm 编程实践的实践报告,涵盖了安装 Maven、使用 Maven 编译运行代码和 mvn 打包等内容。报告中还包括了实验环境的配置、实验内容...

    Maven编译不兼容解决方案

    eclipse 中编译、运行都正常,但是如果用maven的打包命令 mvn clean package 进行打包时会发现有类型错误

    spring 扫描jar maven 打包

    2. **Maven打包过程** Maven是一个强大的项目管理工具,它可以帮助开发者编译、测试、打包、部署Java应用。在Maven中,打包(package)目标是用来创建项目的最终输出,如JAR或WAR文件。默认的打包类型取决于项目的`...

    maven+bat打包

    在Maven的POM.xml文件中,我们可以配置各种插件来执行特定的任务,如编译代码、运行测试、打包应用等。 在"maven+bat打包"的场景中,POM.xml文件中会包含一个特定的插件配置,用于执行自定义的批处理脚本。这个脚本...

    Maven发布Jar包中文乱码解决方法

    这种问题的出现通常是因为 Maven 在编译和打包过程中使用的字符集与系统默认字符集不兼容所致。在 Windows 平台上,默认的字符集是 GBK,而 Maven 的默认字符集是 UTF-8。 二、解决方法 要解决 Maven 发布 Jar ...

    swf.rar_flex_maven 编译flex_maven flex pom_maven flex 编译_swf开发

    6. **测试和部署**: Maven还可以帮助你执行单元测试(如果有)、打包项目以及部署到服务器。例如,`mvn test`用于运行单元测试,`mvn package`会生成最终的可部署文件。 7. **源代码管理与团队协作**: 由于所有的...

Global site tag (gtag.js) - Google Analytics