BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

在Flexmojos中结合使用Flex和Maven – 第1部分:初期步骤

| 作者 Justin J. Moses 关注 0 他的粉丝 发布于 2011年10月27日. 估计阅读时间: 38 分钟 | 如何结合区块链技术,帮助企业降本增效?让我们深度了解几个成功的案例。

目录

需求

预备知识

中继到高级Flex知识

需要的其他产品

用户水平

中级

需要的产品

示例文件

在构建自动化和项目管理方面,Maven已轻车熟路。它在Java领域中存在许多年了,是许多优秀的企业项目的基础。它提供了依赖关系管理能力和它所提倡的约定是它在许多企业开发人员的工具包中的地位的有力保证。

幸运的是,主要归功于开源社区的努力工作,尤其是Marvin Froeder (@velobr),Flash领域的开发人员可在他们的Flex、AS3和AIR构建版本中利用Maven。它以Maven插件Flexmojos的形式使用。

这一系列的文章将介绍Maven的组成,以及如何使用Flexmojos插件管理Flex项目的每个方面,从构建和测试,一直到ASDoc支持和代码范围报告。

这是这个3部分系列的第一篇文章。本文将概述Maven和一些术语、Flexmojos,还提供了一个简单的Flex项目供您起步。本系列的第二篇文章将介绍项目设置和自动化、Flash Builder集成、单元测试和多方面项目。最后一篇文章将深入介绍Nexus、RSL、运行时模块、部署和构建版本分析。

Maven案例

为什么开发人员需要构建工具?

在过去几十年来,软件开发中的一项最受关注的运动就是敏捷软件开发。对于不熟悉它的人而言,敏捷通过小型、可量化的增量来促进开发。为了在项目不断变化的情况下实现敏捷,通常采用持续集成来确保每个构建版本的稳定性和质量。这样,需要有一个构建产品的蓝图,以及一种在每次成功构建后自动测试应用程序的机制。

除了实现定期自动化构建,使用一个构建或控制脚本还会带来其他回报。首先,它可确保每个开发人员的职责明确。随着向源代码控制管理工具(以下简称SCM)的每次签入生成一个构建版本,每位开发人员会负责确保构建版的成功。其次,它为实际项目组成提供了单一联系点。不会使构建参数在每个开发人员的机器或IDE上稍有不同,每位开发人员从相同的脚本构建,确保构建(以及项目设置)过程是SCM的一部分。最后也是最重要地,它确保产品的封装和部署会不断进行测试和细化,使转向生产环境的关键操作得到良好确立。

那么为什么选择Maven?

Flex领域的许多功能都兼容Apache Ant——一个简单的任务运行工具,允许开发人员以要运行的各种流程和要传递的参数的形式编写一系列任务。

另一方面,Maven通过在每个流程中进行约定假设,减轻了构建版本中的杂乱程度。无需显式表明在每个操作期间必须发生什么(比如传递给编译器的参数),Maven插件会为您确定默认的设置,忽略不需要的配置。与Ant不同,它在本地存储库中管理依赖关系,动态下载它缺少的内容。Maven使用POM(项目对象模型)文件(更多信息将在“基础知识”一节中介绍)来管理项目,这些文件支持在模块化的应用程序之间共享和继承项目设置。

如何构建Flex、AIR和AS3项目?

要使用Maven构建和管理Flex、AIR和AS3项目,您需要Flexmojos插件。像所有Maven插件一样,它已在执行项目期间(在根据需要引用和运行它时)已下载。它将设置转换为适用于mxmlc、compc的参数——分别对应于SWF和SWC编译器。不仅仅是构建,它还提供了自动化的单元测试、代码范围报告、运行时模块、RSL支持、HTML包装器、WAR部署和ASDoc输出。

对于最新的Flexmojos版本、网站文档和目标清单(在编写本文时为v4.0-RC2),请参见插件信息

注意:尽管Flexmojos位于Sonatype.org上,但它与它们没有任何其他形式的关联。Flexmojos是一个开源计划,最初由一名开发人员倡导,很巧的是这位开发人员也为Sonatype工作(Marvin Froeder)

基础知识

在深入介绍Flexmojos之前,我将介绍一下Maven的基础知识。

约定高于配置

在本质上,Maven提倡约定高于配置。简单来讲,如果您没有显式声明某项操作应该如何完成,Maven将按照约定执行。因此,每位新开发人员都应该理解这里的约定。实际上,这真是不熟悉Maven的开发人员常常无谓地困扰的原因——Maven对浏览了手册的开发人员不是很宽容。(相信我——这源于我的痛苦经历。)

分层结构

Maven具有分层结构。在项目方面,每个项目可以有一组模块,这些模块本身也可以拥有要构建的模块,等等。模块可从父模块继承设置,可以根据需要改写它们。在依赖关系方面,Maven将在一组远程存储库中查找和下载执行所需要的依赖关系。这些存储库中的每一个本身可以委托给其他远程存储库。

项目对象模型(POM)

一种Maven脚本称为POM——项目对象模型。它是一种XML文档,列出可在项目上执行的各种操作。默认情况下,Maven在当前的执行文件夹中查找pom.xml。

以下是一个示例POM:

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.justinjmoses.flexmojos-introduction</groupId>
    <artifactId>flexmojos-simplist</artifactId>

    <version>0.1-SNAPSHOT</version>

    <packaging>swf</packaging>

    <build>
        <sourceDirectory>src/main/flex</sourceDirectory>

        <plugins>
            <plugin>
                <groupId>org.sonatype.flexmojos</groupId>
                <artifactId>flexmojos-maven-plugin</artifactId>
                <version>4.0-RC2</version>

                <extensions>true</extensions>
            </plugin>
        </plugins>
    </build>
    
    <dependencies>

        <dependency>
            <groupId>com.adobe.flex.framework</groupId>
            <artifactId>flex-framework</artifactId>
            <version>4.5.1.21328</version>

            <type>pom</type>
        </dependency>
    </dependencies>
</project>

注意:这只是一个用于演示结构的简单POM,不是一个完整的实现。

在上面的示例中,您可以看到一些基本特性:

  • 此脚本为项目定义了groupId、artifactId、version和packaging(更多相关信息将在“工件”一节中介绍)。
  • 它演示了如何提供一个源代码位置供Flexmojos查找.as和.mxml文件。在本例中,我使用约定的src/main/flex(更多相关信息将在下一篇文章中介绍)。
  • 它详细说明了将编译SWF文件(使用mxmlc)的Flexmojos插件。
  • 它显示了对Flex 4.5.1框架本身的单一项目依赖关系。

注意:所有POM都继承自Maven超级POM,该POM包含Maven所假设的许多约定。在执行时,Maven将来自您的POM的配置合并到超级POM中。关于超级POM的更多细节,请参阅Maven指南

工件

每个构建版本生成一个工件(通常是每个POM一个)。一个工件是一个操作或流程的结果。工件可分类为groupId、artifactId、version和packaging (type) 。构建流程生成工件并将它们输出到目标文件夹中。

groupId类似于一个包名称——通常为机构和产品的反向域。artifactId是您产品的名称或标识符。version是您产品的SNAPSHOT或版本编号(请参见“版本控制”一节)。packaging(type)指定工件表示何种类型的包——对于Flex项目,您通常会使用swc、swf、air、pom或zip中的任一个。

例如,Flex框架(4.5.1)本身为:

groupId: com.adobe.flex.framework
artifactId: flex-framework
version: 4.5.1.21328
packaging: pom

注意:您可能想知道为什么flex-framework为一个POM,而不是一个SWC或SWZ。这是因为Flex框架由一组依赖关系组成。有哪些依赖关系?打开Flash Builder,创建一个新Flex项目,展开您紧挨项目下列出的Flex SDK(参见图1)。出于方便,有一个捆绑了这些依赖关系的POM。

如果您希望看到此POM的内容,请通过这个远程位置访问它。

图1. Flex框架中的依赖关系

您可以自行决定您项目的相关groupId、artifactId和version。跟往常一样,一致性是关键。

版本控制

一个重要的Maven约定是版本和快照之间的区别。尽管项目的状态不稳定,但每个版本都带有一个-SNAPSHOT后缀,以指定它不是一个稳定的版本。当构建时,Maven将该版本是为一个快照构建版本,继续向您存储库中的相同位置部署后续迭代(在每次后续部署时使用时间戳后缀)。另一方面,会为每个构建版本构建和部署一个发行版。因此,您可以相信工件和其他内容的发行版本,假设它们从未更改。

一般而言,在准备生成发行版之前,您的项目将构建为快照(比如0.0.1-SNAPSHOT),您将不使用后缀构建和部署一次,然后增量修改版本并重新应用后缀(例如,部署0.0.1,然后将版本递增为0.0.2-SNAPSHOT)。

除此之外,实际的版本号可以是任意的,由您自行决定。一条经验规则是保留一个主要、次要和增量编号(比如1.3.9)——如果您在未来希望指定依赖关系范围,这将很有帮助。如果需要,您也可以应用一个限定符(比如0.5.2-alpha3)。

存储库

Maven的每次安装会创建一个本地存储库。这个存储库通常名为.m2,位于用户的主目录中。在Windows 7上,它位于/Users/[username]/.m2中;在OS X和Linux上,它为~/.m2。

工件依照另一条Maven约定存档在存储库中:

/groupId/.../artifactId/version/artifactId-version.extension

从图2中可以看到,上面的Flex框架依赖关系的位置将为:

~/.m2/repository/com/adobe/flex/framework/flex-framework/4.5.1.21328/flex-framework-4.5.1.21328.pom

正如前面所述,这个flex-frameworkPOM是另一个工件,为您捆绑了依赖关系。因此,它与其他所有内容一起存档在您的存储库中。

图2. 依据Maven约定自动存储Flex框架工件

运行Maven

Maven是一个命令行流程。尽管一些第三方工具可以将Maven集成到现代IDE中,但本文仅将关注命令行Maven流程。(请随时关注下一篇文章,其中将介绍Flash Builder集成。)

在您的命令行路径(PATH)上安装和设置了Maven库之后,就可以构建项目了,方法是进入项目的根文件夹(其中包含pom.xml文件)并运行:

mvn install

这将启动从POM创建一个工件、将它保存到target文件夹中,然后将它安装在您的本地存储库中的流程。如果在此过程中缺少任何依赖关系,Maven将尝试下载它们并将其添加到您的本地目录中。

术语

目标、阶段和生命周期

Maven流程包含3个部分:目标、阶段和生命周期。

  • 目标是一项操作。它可以是简单地将一个工件安装到本地存储库中,也可以是复杂地运行一系列自动化的单元测试。
  • 阶段是一组目标。任何阶段都可以绑定一个或多个目标。请包含清理(clean)、编译(compile)和测试(test)。
  • 生命周期是一个阶段序列。当您运行一个典型生命周期中的一个阶段时,您会运行该阶段即之前的所有阶段。两个主要的生命周期是clean和默认的生命周期。

每个生命周期内的实际阶段和其中的目标同时来自您的POM内的封装文件(比如jar、swc或swf)和插件列表。

奇怪的组合:清理和安装

Maven的最常见的执行过程是一种干净安装。它的执行命令为:

mvn clean install

这个简单的命令运行clean生命周期,然后运行默认的生命周期,一直到包含install阶段。在本质上,它执行以下步骤:

  • 首先,Maven在当前文件夹中检查任何pom.xml。从该文件,它确定基于封装文件(jar、swc、swf等)和定义的任何插件确定运行哪些阶段和目标。
  • 然后它运行clean阶段。该阶段默认会从当前目录中的目标文件夹删除所有文件。
  • Maven然后开始构建,运行默认的生命周期,一直到包含install阶段。默认情况下,这包括验证、编译和测试。但是,POM中描述的具体的封装文件和/或插件将确定在实际安装之前和期间完成的实际目标和阶段。

插件

插件提供目标,并可选地将它们绑定到新的或现有的阶段。事实上,Maven中全部是插件。默认生命周期内的所有核心功能都由核心插件提供。

例如,编译器插件定义两个目标:compile和testCompile。您可以通过编译器插件页面看到它们的设置。这两个目标分别绑定到两个独立的阶段:compile和test-compile。

当独立运行时,所有目标都带有相关插件的前缀。例如,运行一个目标涉及到以下模式:

plugin:goal

所以,单元测试的编译将通过以下命令完成:

mvn compile:testCompile

实际上,Flexmojos本身是一个插件,它将各种阶段绑定到构建版本,无论是SWC/SWF封装文件内还是插件本身内的阶段。如果您希望运行默认生命周期外部的一个目标(比如ASDoc生成),您可以使用如下命令显式运行它:

mvn flexmojos:asdoc

如果您希望执行干净安装,然后运行ASDoc,可以使用:

mvn clean install flexmojos:asdoc

Flexmojos插件

前面已经提到,Flexmojos是一个插件,它在本质上会将SWF和SWC封装文件添加到您的POM中,确保Flexmojos生命周期将在标准构建过程中采用。

图3显示了默认SWF和SWC生命周期中执行的插件和目标:

图3. SWF和SWC生命周期

AIR生命周期与SWF相同,但包含一个在测试运行之后进行AIR签名的额外阶段。关于Flexmojos生命周期的更多信息,请查阅参考文档

依赖关系和存储库

Maven的一种强大的能力是处理依赖关系。

依赖关系是一个工件

每个依赖关系以表示它的工件的形式列出。例如,对FlexUnit 4.0-RC-1的依赖关系类似于:

<dependency>
    <groupId>com.adobe.flexunit</groupId>
    <artifactId>flexunit</artifactId>
    <version>4.0-rc-1</version>

    <type>swc</type>
</dependency>

因此,POM可以引用来自其他POM的工件,并且在一个构建版本内,Maven将自动确定构建顺序。下一篇文章将深入介绍这一点。

本地存储库

依赖关系位于存储库中。Maven的每次安装都会创建一个本地存储库,通常位于~/.m2中。因为依赖关系位于您的POM中,所以Maven在尝试从远程存储库下载它之前,会首先检查本地存储库。

每次您安装项目,实际上您是在将生成的工件添加到本地存储库中。

存储库查找

当构建时,如果Maven无法找到一个依赖关系,它将在您定义的任何远程存储库中查找。要找到存储库,Maven将在以下区域查找repository和pluginRepository定义:

  • 在执行POM中
  • 在父POM中(如果有)
  • 在构建版本中使用的任何settings.xml中(通过-s命令行选项配置)
  • 在用户级设置中(~/.m2/settings.xml)
  • 在全局级别设置中(M2_HOME/conf/settings.xml)

它然后在Maven中央存储库(在超级Maven POM中定义,所有POM都继承自它)中搜索。如果无法找到它,您的构建过程将中断,直到您修复了该问题。

查找Flex和Flexmojos依赖关系

那么,您的本地Maven安装如何知道在何处查找您的POM中列出的Flex和Flexmojos依赖关系?

Flexmojos本身位于Maven中央存储库中,所有POM所继承的超级POM中引用了它。这意味着,您无需向您的POM中添加任何内容,Maven就可以查找并下载它。如果您希望手动搜索Maven中央存储库,请访问search.maven.org

不幸的是,最新的Flex SDK和编译器依赖关系不再Maven中央存储库中。您需要将以下存储库信息添加到您的POM中、您本地存储库的用户级settings.xml中或您的Maven安装的conf文件夹下的全局级settings.xml中。这样,当Maven运行时,它知道在何处查找Flex框架和Flex编译器:

<repository>
    <id>flex-mojos-repository</id>
    <url>http://repository.sonatype.org/content/groups/flexgroup</url>
</repository>

<pluginRepository>
    <id>flex-mojos-repository</id>
    <url>http://repository.sonatype.org/content/groups/flexgroup</url>
</pluginRepository>

通过Nexus查找远程存储库

上面的位置指向一个Nexus存储库。Nexus允许一种同时在内部和外部托管一组工件的情形。

请在以下url中查阅上述Nexus:repository.sonatype.org。尝试在提供的搜索框中搜索各种工件——您可以看到各种类型和每种类型的版本。事实上,这常常是您发现各种依赖关系的哪些发行版可用的方式。我将在第三篇文章中更详细介绍Nexus。

手动将依赖关系添加到本地存储库

如果您无法找到在任何地方托管的存储库怎么办?您可以使用install:install-file手动将工件添加到您的存储库。

例如,假设您希望将as3-signals依赖关系添加到您的构建版本中(as3-signals是一个第三方库,我将使用它作为一个例子)。您可以尝试将以下内容添加到POM中:

<dependency>
    <groupId>org.osflash</groupId>
    <artifactId>as3-signals</artifactId>
    <version>0.8</version>

    <type>swc</type>
</dependency>

但是,如果您尝试构建,您将可能看到与以下信息类似的信息:

[ERROR] Failed to execute goal on project flexmojos-dependencies: Could not resolve dependencies for project org.justinjmoses.flexmojos-introduction:flexmojos-dependencies:swf:0.0.1-SNAPSHOT: Could not find artifact org.osflash:as3-signals:swc:0.8 in flex-mojos-repository (http://repository.sonatype.org/content/groups/flexgroup) -> [Help 1]

Maven无法找到列出的依赖关系。您可以尝试访问互联网,查看它是否托管在某个地方。如果找到,您可以将该存储库位置添加到您的POM或设置文件中。也可以简单地本地安装依赖关系。假设您位于与文件as3-signals-0.8.swc相同的文件夹,您可以运行一下命令来将工件添加到您的存储库:

mvn install:install-file 
-Dfile=as3-signals-0.8.swc 
-DgroupId=org.osflash
-DartifactId=as3-signals 
-Dversion=0.8 
-Dpackaging=swc

注意:这里我从install插件运行了install-file目标。我们使用-D选项传入参数。关于这些参数的详细信息,您可以查阅插件的install-file目标文件

示例POM

以下是一个简单的示例POM。我添加内部注释来解释POM的每个方面。以下是一个Flex 4.5.1示例。

开放是一种不错的标准:一些XML命名空间和一个POM版本。模型版本表示要使用的对象模型的版本,进而表示您将继承的Maven超级POM。这个编号会不会经常更改,自Maven 2以来就已是4.0.0:

<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>

然后是此POM的工件信息(和可选的名称):

<groupId>org.justinjmoses.examples</groupId>
<artifactId>flexmojos-dependencies</artifactId>
<name>Flexmojos Dependencies Example</name>
<version>1.0.0-SNAPSHOT</version>

然后,我声明工件的类型。在本例中它为SWF,它由Flexmojos提供,决定了默认的构建生命周期中的目标和阶段:

<packaging>swf</packaging>

接下来,我显式定义一个属性,很像您在Ant中所做的一样。我设置可重用的常量。这里我定义最新的Flex 4.5.1版本(准确的编号可在Flex SDK页面上找到):

<properties>
<flex.version>4.5.1.21328</flex.version>
</properties>

现在,在构建版本内,我告诉Maven在何处(相对于当前的POM)查找源文件。默认情况下,Flexmojos将在源代码目录及其所有子文件夹中查找*.mxml和*.as文件:

<build>
<sourceDirectory>src/main/flex</sourceDirectory>

然后,我指定Flexmojos作为构建版本本身的版本。这里我使用了最新的Flexmojos版本4.0-RC2:

<plugins>
<plugin>
<groupId>org.sonatype.flexmojos</groupId>
<artifactId>flexmojos-maven-plugin</artifactId>
<version>4.0-RC2</version>

扩展设置为true,以确保Flexmojos默认生命周期通过上面定义的默认SWF封装文件来执行:

<extensions>true</extensions>

该配置列出构建版本内所有目标的所有选项。我也可以在命令行使用-D选项设置这些选项。下一篇文章将更详细地介绍配置设置:

<configuration>

对于SWF构建,我定义了主要Application文件(相对于上面定义的源文件夹)。默认情况下,Flexmojos会在源目录中中查找一个.mxml文件,所以这是可选的,但我还是添加了它:

<sourceFile>./Main.mxml</sourceFile>

我喜欢关闭没有构造函数编译器的警告——我不需要看到缺乏构造函数的警告:

<compilerWarnings>
<warn-no-constructor>false</warn-no-constructor>
</compilerWarnings>
 
</configuration>
</plugin>
</plugins>
</build>

现在列出我的SWF应用程序中的所有依赖关系,以确保它可以构建:

<dependencies>

第一个依赖关系是Flex框架本身。所有框架SWC都捆绑在POM中,所以我可以确保它们将位于构建版本中:

<dependency>
<groupId>com.adobe.flex.framework</groupId>
<artifactId>flex-framework</artifactId>
<version>${flex.version}</version>
<type>pom</type>
</dependency>

这个具体的项目使用as3-signals— 一种第三方依赖关系。如果您希望自行运行此项目,必须手动执行mvn install:install-file来将as3-signals依赖关系添加到您的本地存储库中(参见上文):

<dependency>
<groupId>org.osflash</groupId>
<artifactId>as3-signals</artifactId>
<version>0.8</version>
<type>swc</type>
</dependency>
 
</dependencies>

最后,我添加构建版本需要的存储库。(您可以将这些条目放在您的~/.m2/settings.xml文件中,以避免将它们包含在每个POM中):

<repositories>

首先,定义项目依赖关系的存储库:

<repository>
<id>flex-mojos-repository</id> 
<url>http://repository.sonatype.org/content/groups/flexgroup</url>

而且我只希望使用发行版,而不是快照。这些是默认值,但我还是添加了它们:

<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
 
</repository>
</repositories>

然后,我定义了插件(在本例中为Flexmojos和Flex编译器)的存储库。请注意,我为此存储库使用了与上述依赖关系相同的URL:

<pluginRepositories>
<pluginRepository>
<id>flex-mojos-plugin-repository</id>
<url>http://repository.sonatype.org/content/groups/flexgroup</url>
</pluginRepository>
</pluginRepositories>
 
</project>

关于示例项目和它们的POM,请查阅我在github上的flexmojos-introduction项目。这个具体的示例来自第三个项目(标为Dependencies)。

注意:在您大胆地开发Maven的过程中,您会构建一组最适合您的POM。最初,您可以从其他项目上使用的POM开始,然后根据需要删除和添加功能和配置设置。总是删除您不需要的内容,这会使问题的检测更加容易,不会出现混乱。

延伸阅读

Maven是一个强大的工具,它经常被误解和误用,被过度地随意转换。通过它的许多约定,Maven简单、有效地解决了许多常见的问题。当所有一切正常运转时,生活就会变得美好。但是,当出现错误时,您将会庆幸您花时间学习了这些约定,节省了大量不知所措的时间。如果您遇到了困难,可以返回查看第一条原则。删除您的POM中所有不必要的内容,尝试隔离问题(听起来很像调试,是不是?)许多问题都是在开发人员在网络上找到的POM中剪切和粘贴内容时发生的——他们自己的脚本变成了配置设置的大杂烩。

您可以下载Maven,从Github获取示例代码,并对各种构建版本进行修补。

这是一个3部分系列的第一篇文章。请随时关注下一篇文章,届时我们将深入剖析更复杂的项目,探讨Flash Builder集成、单元测试和自动项目设置。

以下是一些有用的资源:

clip_image009

本作品依据Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License授权

查看原文:Flex and Maven with Flexmojos – Part 1: First steps

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我
社区评论

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT