使用 Maven 构建复杂的 Flex 项目 [英] Use Maven to build complex Flex project

查看:24
本文介绍了使用 Maven 构建复杂的 Flex 项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在考虑用 Maven 替换我们非常专有的构建环境.当前的解决方案是中央构建的内部开发,为了更容易的本地开发,我在 Eclipse/Flex IDE 内编译,并有一个 ANT 脚本将所有内容一起复制到我的本地 Apache 目录(即我的 ant 文件不执行完整构建并且还依赖于在本地提供所有项目).

我们使用带有 Flash Builder 插件(即 Flex4)的 Eclipse 3.6.1 (Helios),针对 Flex SDK 3.5 (FlashPlayer 10.0) 和相当多的项目,包括在运行时加载的 .swc 库项目和 .swf 模块,包括每个资源.我们还使用外部链接/运行时共享库​​(一个很大的 sharedlibraries.swf 里面包含所有内容,即部署中不需要 .swc 文件).我已经安装了 Maven 3.0.2,使用 Sonatypes flexmojos-maven-plugin3.7.1(因为它似乎比 Servebox 的更活跃).我已经为每个 Eclipse 项目手动创建了 pom 文件,以确保一切正常,而且 Eclipse-Maven 集成似乎缺乏 Flex 支持.我已经定义了适当的编译器和依赖项参数,以便所有单独的项目都能正确编译 - 即生成的 .swf 文件确实会生成我们应用程序的工作版本.我还阅读了 Sonatype 的Maven by Example"一书,并看了在他们的Maven: The Complete Reference",同时在谷歌搜索平行.

我正在努力解决项目的最终组装以及其他工件(样式表).我不完全理解Maven 方式",并且还怀疑 Maven 是为 Java 量身定制的,因此我的 Flex 项目让我有点不知所措.

我的项目的基本结构:

  • 外部库:我已将那些带有 install:install-file 的库添加到我的存储库中,这里没有问题
  • 自己的库项目:它们每个都生成一个可以在其他项目中使用的 .swc 工件,Maven 依赖项处理正常工作,这里没有问题
  • 自己的 swf 模块项目:我们的应用程序在运行时加载 swf 文件,这些文件反过来又需要一些额外的资源(stylesheet.swf 文件、本地化字符串作为单独的 .xlf 文件、配置文件等).正是这些让我苦恼的.

我的 swf 项目的布局:

  • bin-debug/ IDE 构建使用,Maven 构建未使用/忽略
  • src/ Flex 源代码(.as 和 .mxml 文件)
  • target/ Maven 目标目录
  • WebContent/ 包含补充文件的目录,需要与 .swf 工件一起逐字复制到目标工件(目录或 zip 文件)中
  • styles/ 需要编译成 .swf 样式表文件的 Flex .css 文件,这些是主项目 swf 和 WebContent 的附加工件(每个 .css 一个,用于不同的主题)/内容

我在 Eclipse 中使用平面层次结构,即我的主 pom 文件放置在一个文件夹中,该文件夹是所有项目文件夹的同级文件夹.示例:

project_swf/src/...project_swf/WebContent/assets/labels.xlfproject_swf/WebContent/config/config.xmlproject_swf/pom.xmllib_swc/src/...lib_swc/pom.xmlmaster_build/pom.xmlmaster_build/swf-assembly.xml

我已经使用这个ma​​ster pom成功地创建了一个主构建"来构建我所有的swc和swf项目:

<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/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><name>Dragon Master Build</name><description>此项目可用于构建和打包客户端应用程序</description><属性><!-- 这需要与 groupId 标签相同,遗憾的是不能使用 ${} 符号直接访问--><group-id>de.zefiro.maven.example</group-id><!-- 插件 swf 文件的参数,在客户端显示为插件内部版本号"--><!-- TODO 应该是中央系统上的内部版本号--><zefiro.plugin.buildno>local_dev_mvn</zefiro.plugin.buildno><!-- 使用外部引用构建所有 SWF 文件(sharedlibraries.swf 除外)(注意:Flexmojo 在这里滥用了范围"概念,但目前没有更好的方法)--><zefiro.swf.scope>外部</zefiro.swf.scope></属性><groupId>de.zefiro.maven.example</groupId><artifactId>full_build</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><构建><sourceDirectory>src/</sourceDirectory><插件><插件><groupId>org.sonatype.flexmojos</groupId><artifactId>flexmojos-maven-plugin</artifactId><version>3.7.1</version><extensions>true</extensions><!-- 我们需要使用 Flex SDK 3.5 进行编译 --><依赖><依赖><groupId>com.adobe.flex</groupId><artifactId>编译器</artifactId><version>3.5.0.12683</version><type>pom</type></dependency></dependencies><!-- Flex 编译的配置--><配置><targetPlayer>10.0.0</targetPlayer><增量>假</增量><debug>false</debug><runtimeLocales></runtimeLocales><locale>en_US</locale><优化>真</优化><showWarnings>true</showWarnings><strict>true</strict><useNetwork>true</useNetwork><allowSourcePathOverlap>true</allowSourcePathOverlap><定义声明><财产><name>ZEFIRO::META_INFO</name><value>"buildno=${zefiro.plugin.buildno}"</value></属性></definesDeclaration></配置></插件></plugins></build><依赖项><依赖><groupId>com.adobe.flex.framework</groupId><artifactId>flex-framework</artifactId><version>3.5.0.12683</version><type>pom</type><排除事项><!-- 确保排除默认的playerglobal"传递依赖项(对于 SDK 3.5 来说是版本 9,但是,我们需要版本 10)--><排除><groupId>com.adobe.flex.framework</groupId><artifactId>playerglobal</artifactId></排除></排除项></依赖><依赖><groupId>com.adobe.flex.framework</groupId><artifactId>playerglobal</artifactId><!-- 此工件版本必须与此项目中使用的 flex SDK 版本匹配--><version>3.5.0.12683</version><!-- 分类器指定目标 Flash Player 主要版本(SDK 3.5 的默认值为 9)--><分类器>10</分类器><type>swc</type></依赖>[...所有项目需要的更多依赖项...]</依赖项><模块><module>../lib_swc</module><module>../project_swf</module>[...调用我所有的项目...]</模块></项目>

然后我可以使用这个简单的 POM 编译我的 swc 库项目:

<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>de.zefiro.maven.example</groupId><artifactId>full_build</artifactId><version>1.0-SNAPSHOT</version><relativePath>../master_build</relativePath></父母><name>示例库项目</name><artifactId>lib_swc</artifactId><packaging>swc</packaging><依赖项><依赖><groupId>${group-id}</groupId><artifactId>some_other_library</artifactId><version>${project.version}</version><!-- 我可能也应该研究依赖/版本控制,但现在这可行--><!-- 注意:这里没有范围",swc 文件将构建为合并到代码中"的样式.需要,因为传递依赖项不适用于 Maven/Flex - 我们对最终 swf 项目依赖项使用外部"范围 --><type>swc</type></依赖></依赖项></项目>

还有我的 swf 项目与这个 POM:

<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>de.zefiro.maven.example</groupId><artifactId>full_build</artifactId><version>1.0-SNAPSHOT</version><relativePath>../master_build</relativePath></父母><name>示例 SWF 模块</name><artifactId>project_swf</artifactId><packaging>swf</packaging><构建><!-- 这个名字需要精确指定,因为运行时会按照它在配置 xml 中指定的方式加载它 --><finalName>SampleProjectModule1</finalName><!-- 定义主源文件,它为某些项目自动选取,必须为其他项目指定.从父级继承编译器参数.--><插件><groupId>org.sonatype.flexmojos</groupId><artifactId>flexmojos-maven-plugin</artifactId><version>3.7.1</version><配置><sourceFile>project_swf_master_file.as</sourceFile></配置></插件><插件><插件><artifactId>maven-assembly-plugin</artifactId><配置><描述符><描述符>../master_build/swf-assembly.xml</descriptor></描述符></配置><执行><执行><id>WebContent-packaging</id><phase>包</phase><goals><goal>单个</goal></goals></执行></执行></插件></plugins></build><依赖项><依赖><groupId>${group-id}</groupId><artifactId>project_swc</artifactId><version>${project.version}</version><scope>${zefiro.swf.scope}</scope><!-- 告诉 Flex Mojo 我们要使用运行时共享库​​ (rsl) 进行编译 --><type>swc</type></依赖>[...]</依赖项></项目>

据我了解,每个 POM 文件都会生成一个目标文件(使用包装标签指定),并且在使用 Flex mojo 时,这需要采用 swf 或 swc 格式.我似乎无法在此处指定多个目标,并且还努力将我的资源文件包含在内(Flex copy-resources 复制我不需要的 html 包装器(对于每个项目),普通资源标签复制资源,但不要不打包它们).现在我当前的工作版本是指定一个自己的程序集描述符,它将我的目标 .swf 文件与 WebContent/文件夹捆绑到一个 zip 文件中.Maven 支持 jar/war/bin 文件,但那些似乎期望某些条件为真,这不适用于我的 Flex 项目(例如,我没有 web.xml)

swf-assembly.xml:

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"><id>WebContent</id><格式><格式>zip</格式></格式><includeBaseDirectory>false</includeBaseDirectory><文件集><!-- 获取基础 swf 工件(仅,不是在那里生成的其他东西)--><文件集><目录>${project.build.directory}</directory><outputDirectory>/</outputDirectory><包括><include>*.swf</include></包括></fileSet><!-- 添加 WebContent 文件夹--><文件集><目录>FCP内容</目录><outputDirectory>/</outputDirectory></fileSet></fileSets></组装>

现在我已经获得了包含 .swf 文件和包含我的 .swf 文件和我的 WebContent/资源的 zip 文件的目标目录.它还在调用mvn install"时放置在 Nexus 存储库中,因此这看起来是向前迈出的一大步.虽然我很乐意做完全不同的事情,如果这更好的话,因为我的最终目标是有一个单一的目录(或包含它的 zip/war 文件),其中包含一些静态文件(我们的 html 包装器和加载器 swf + configuration.xml),并且对于我们的每个 swf 项目(我们在运行时加载的模块)一个包含 .swf 文件和 WebContent/资源的目录 - 即我现在可以为每个项目创建的 zip 文件的内容.

index.html加载器.swf配置文件project_swf/SampleProjectModule1.swfproject_swf/assets/labels.xlfproject_swf/config/config.xmlproject2_swf/module2.swfproject2_swf/cool_colors_stylesheet.swf

所以我的问题是:如何定义这样一个以这种格式创建最终程序集的 Maven 主项目?如果没有其他办法,一个有效的 ANT 文件可能是可以接受的,尽管我读过它 Maven 敦促我们远离那些黑客 :)

我还需要编译样式表文件,这些文件是 swf 项目的附加工件.我将为此发布一个单独的问题.

解决方案

我的解决方案有点复杂,感觉很脏" - 我认为可能有更干净的方法,但至少我现在已经运行了.

基本上,我使用 Maven-assembly-plugin 来创建中间 zip 存档('war' 工作得同样好),其中包含 swf 可执行文件以及我正在创建的每个插件的任何必要的静态资产(我们是使用类似于 Eclipse 工作方式的类似 OSGi 的动态加载器,其中一个静态文件是 plugin.xml,其他是翻译文件,它们都不能嵌入到 .swf 中).Maven 将 .swf 文件以 Maven 文件名表示法存储为主要工件 - 我完全无视 - 和我的 zip 存档(根据 finalName 标签带有 .swf 名称).用于此的 POM 和程序集文件如我的原始问题所示.

我添加了一个空白的装配项目,其唯一目标是依赖并因此包括我的所有其他项目.该项目的输出是我最终的真实"工件,然后我可以将其用于分发和部署.由于我不想将我的 Eclipse 工作区与太多帮助项目聚集在一起,我打破了 Maven 项目和 Eclipse 项目的 1:1 关系:我的 Maven 程序集插件位于我的 master_build 项目中的子目录assembly"中.我在我的主 pom (master_build/pom.xml) 中为它添加了一个模块语句,它将作为最后一个项目在反应器中执行.(由于给定的依赖关系,排序会自动完成 - 如果您将其指定为第一个模块并且它没有最后执行,那么您正在构建您不需要的项目:)

我还使我的装配项目 POM 成为我的主 POM 的子项.这不是必需的,但通过这样做,我可以继承我定义的 Maven 属性.它还继承了对 Flex 编译器的调用,但由于这里没有任何可编译的内容,这也无妨.天啊.

这是 POM:

<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/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><父母><groupId>de.zefiro.maven.example</groupId><artifactId>full_build</artifactId><version>1.0-SNAPSHOT</version><relativePath>../</relativePath></父母><groupId>${group-id}</groupId><artifactId>full_assembly</artifactId><name>总决赛</name><version>${project.parent.version}</version><packaging>pom</packaging><!-- 请注意,这里是 POM,而不是 war 或 zip --><构建><插件><插件><artifactId>maven-assembly-plugin</artifactId><version>2.2.1</version><配置><描述符><descriptor>final-assembly.xml</descriptor></描述符></配置><执行><执行><id>最终包装</id><phase>包</phase><目标><目标>单</目标></目标></执行></执行></插件></plugins></build><依赖项><依赖><groupId>de.zefiro.maven.example</groupId><artifactId>包装器</artifactId><version>1.0</version><type>war</type></依赖><依赖><groupId>${group-id}</groupId><artifactId>project_swf</artifactId><version>${project.version}</version><type>zip</type><classifier>WebContent</classifier><!-- 需要是打包 zip 文件的汇编 xml 的 ID --></依赖>[...应该打包的所有其他项目...]</依赖项></项目>

遵循程序集描述符.有关详细信息,请参阅程序集描述符文档.

<汇编xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd"><id>FinalAssembly</id><格式><format>war</format><!-- 可以是 zip 或 war,具体取决于您的意愿--></格式><includeBaseDirectory>false</includeBaseDirectory><依赖集><依赖集><包括><include>de.zefiro.maven.example:wrapper:war:*</include></包括><unpack>true</unpack></dependencySet><依赖集><包括><include>${group-id}:project_swf:zip:WebContent:${project.version}</include></包括><useProjectAttachments>true</useProjectAttachments><unpack>true</unpack><outputDirectory>sample_project_1</outputDirectory></dependencySet>[...列出与 POM 文件中相同的项目...]</dependencySets></组装>

我有一个来自不同部门的档案,我正在使用它.它包含 HTML 包装器和运行的主 Flex 应用程序(然后根据配置文件和各个项目的 plugin.xml 元数据从子目录加载我的所有插件).这被放置在输出存档根目录中.所有其他项目都是我自己创建并放置在各个子目录中的项目,因此我没有在这里使用通配符.因为我想要一个包含所有合并文件的单一档案,所以我使用了 dependencySet 的解包选项.

请注意,在各个 swf 插件项目的程序集描述符中声明的 ID 现在用作 pom 文件依赖项部分中的分类器,以及程序集描述符中 Maven 位置的一部分.包装类型相同,我在这里选择了 zip.由于这仅用于中间存档,因此 zip 很好,对于最终组装,可以选择不同的格式.

从同一个父级继承,我可以重用我的 Maven 属性,这些属性也在程序集描述符中可用.

可以通过复制现有项目并将其添加到以下位置来添加新项目:

  • master_build/pom.xml 作为模块
  • 依赖项部分中的master_build/assembly/pom.xml
  • master_build/assembly/final-assembly.xml 作为依赖集

最终的工件是一个战争文件,其中包含:

sample_project_1/SampleProjectModule1sample_project_1/assets/labels.xlfsample_project_1/config/config.xmlother_data/configuration.xml应用程序.swf索引.html

即我所有 swf 项目在其各自子目录中的内容与包含静态文件的 wrapper.war 的内容合并.

它可以从这个位置的存储库中检索:

de.zefiro.maven.example:full_assembly:war:FinalAssembly:1.0-SNAPSHOT

为了为每个插件编译样式表,我使用了相同的基本思想,并将其移至单个项目级别.我将在其他问题

未解决的问题:我无法同时生成文件的调试版本和发布版本.我可以将项目加倍并将它们打包在一起(就像我对样式表所做的那样),或者我可以运行整个 Maven 反应器(对于父 POM 和主程序集)两次,例如不同的 groupId,从而为所有涉及的项目创建两个完全独立的路径.不过,我还没有对此进行进一步调查.

I'm currently looking into replacing our very proprietary build environment with Maven. The current solution is an inhouse development for the central build, and for easier local development I compile inside the Eclipse/Flex IDE and have an ANT script which copies everything together to my local Apache directory (i.e. my ant file does not do the full build and also relies on having all projects locally available).

We're using Eclipse 3.6.1 (Helios) with Flash Builder Plugin (i.e. Flex4), targetting Flex SDK 3.5 (FlashPlayer 10.0) with quite some projects both .swc library projects and .swf modules to be loaded at runtime including resources for each. We also use external linking / runtime shared libraries (with one big sharedlibraries.swf having everything inside, i.e. no need to have the .swc files in the deployment). I've installed Maven 3.0.2, using Sonatypes flexmojos-maven-plugin 3.7.1 (as it seems more active than the one from Servebox). I've manually created pom files for each Eclipse project, to make sure that everything works and also the Eclipse-Maven integration seems to lack Flex support. I've defined appropriate compiler and dependency parameters so that all individual projects compile correctly - i.e. the resulting .swf files do produce a working version of our application. I've also read the "Maven by Example" book from Sonatype and looked at their "Maven: The Complete Reference", while doing lots of googling in parallel.

What I'm struggling with is the final assembly of my project, as well as with additional artifacts (stylesheets). I don't fully understand "the Maven way" and also suspect that Maven is tailored heavily for Java, thus leaving me a bit in the wild with my Flex projects.

Basic structure of my projects:

  • external libraries: I've added those with install:install-file to my repository, no issue here
  • own library projects: they each produce one .swc artifact which can be consumed in other projects, with Maven dependency handling working correctly, no issue here
  • own swf module projects: our application loads swf files at runtime which in turn have some additional resources they need (stylesheet.swf files, localized strings as individual .xlf files, config files, etc). It's those I'm struggling with.

Layout of my swf projects:

  • bin-debug/ used by IDE builds, not used / ignored by Maven build
  • src/ the Flex sources (.as and .mxml files)
  • target/ Maven target directory
  • WebContent/ a directory with suplementary files which needs to be copied to the destination artifact (directory or zip file) verbatim, alongside the .swf artifact
  • styles/ Flex .css files which needs to be compiled into .swf stylesheet files, those are additional artifacts (one for each .css, for different themes) to the main project swf and the WebContent/ content

I'm using a flat hierarchy to work in Eclipse, i.e. my master pom file is placed in a folder which is a sibling to all projects folders. Example:

project_swf/src/...
project_swf/WebContent/assets/labels.xlf
project_swf/WebContent/config/config.xml
project_swf/pom.xml
lib_swc/src/...
lib_swc/pom.xml
master_build/pom.xml
master_build/swf-assembly.xml

I've managed to create a 'master build' building all my swc and swf projects using this master pom:

<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <name>Dragon Master Build</name>
    <description>This project can be used to build and package the client application</description>

    <properties>
        <!-- this needs to be the same as the groupId tag, which unfortunately cannot be accessed directly using ${} notation -->
        <group-id>de.zefiro.maven.example</group-id>

        <!-- parameter to plugin swf files, shown as plugin 'Build Number' in client -->
        <!-- TODO should be a build number on central system -->
        <zefiro.plugin.buildno>local_dev_mvn</zefiro.plugin.buildno>

        <!-- build all SWF files (except sharedlibraries.swf) with external references (Note: Flexmojo abuses the 'scope' concept here, but there is currently no better way) -->
        <zefiro.swf.scope>external</zefiro.swf.scope>
    </properties>

    <groupId>de.zefiro.maven.example</groupId>
    <artifactId>full_build</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <build>
        <sourceDirectory>src/</sourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.sonatype.flexmojos</groupId>
                <artifactId>flexmojos-maven-plugin</artifactId>
                <version>3.7.1</version>
                <extensions>true</extensions>
                <!-- We need to compile with Flex SDK 3.5 -->
                <dependencies><dependency>
                    <groupId>com.adobe.flex</groupId>
                    <artifactId>compiler</artifactId>
                    <version>3.5.0.12683</version>
                    <type>pom</type>
                </dependency></dependencies>
                <!-- configuration for the Flex compilation -->
                <configuration>
                    <targetPlayer>10.0.0</targetPlayer>
                    <incremental>false</incremental>
                    <debug>false</debug>
                    <runtimeLocales></runtimeLocales>
                    <locale>en_US</locale>
                    <optimize>true</optimize>
                    <showWarnings>true</showWarnings>
                    <strict>true</strict>
                    <useNetwork>true</useNetwork>
                    <allowSourcePathOverlap>true</allowSourcePathOverlap>
                    <definesDeclaration>
                        <property>
                            <name>ZEFIRO::META_INFO</name>
                            <value>"buildno=${zefiro.plugin.buildno}"</value>
                        </property>
                    </definesDeclaration>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>com.adobe.flex.framework</groupId>
            <artifactId>flex-framework</artifactId>
            <version>3.5.0.12683</version>
            <type>pom</type>
            <exclusions>
                <!-- make sure to exclude the default 'playerglobal' transitive dependency (which would be version 9 for SDK 3.5, however, we want version 10) -->
                <exclusion>
                    <groupId>com.adobe.flex.framework</groupId>
                    <artifactId>playerglobal</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>com.adobe.flex.framework</groupId>
            <artifactId>playerglobal</artifactId>
            <!-- this artifact version must match the flex SDK version used in this project -->
            <version>3.5.0.12683</version>
            <!-- the classifier specifies the target flash player major version (default is 9 for SDK 3.5) -->
            <classifier>10</classifier>
            <type>swc</type>
        </dependency>

        [... some more dependencies needed by all projects ...]
    </dependencies>

    <modules>
        <module>../lib_swc</module>
        <module>../project_swf</module>
        [... calls all my projects ...]
    </modules>

</project>

I can then compile my swc library projects with this simple POM:

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

    <parent>
        <groupId>de.zefiro.maven.example</groupId>
        <artifactId>full_build</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../master_build</relativePath>
    </parent>

    <name>Sample library project</name>
    <artifactId>lib_swc</artifactId>
    <packaging>swc</packaging>

    <dependencies>
        <dependency>
            <groupId>${group-id}</groupId>
            <artifactId>some_other_library</artifactId>
            <version>${project.version}</version> <!-- I should probably look into dependency/versioning as well, but for now this works -->
            <!-- Note: no 'Scope' here, swc files will be build "merged into code"-style. Needed as transitive dependencies don't work with Maven/Flex - we use 'external' scope for the final swf projects dependencies -->
            <type>swc</type>
        </dependency>
    </dependencies>

</project>

And my swf projects with this POM:

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

    <parent>
        <groupId>de.zefiro.maven.example</groupId>
        <artifactId>full_build</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../master_build</relativePath>
        </parent>

    <name>Sample SWF module</name>
    <artifactId>project_swf</artifactId>
    <packaging>swf</packaging>

    <build>
    <!-- This name needs to be exactly specified, as the runtime will load it as it's specified in the configuration xml -->
        <finalName>SampleProjectModule1</finalName>

        <!-- define the master source file, it's picked up for some projects automatically and must be specified for others. Inherits compiler parameters from parent. -->
        <plugin>
            <groupId>org.sonatype.flexmojos</groupId>
            <artifactId>flexmojos-maven-plugin</artifactId>
            <version>3.7.1</version>
            <configuration>
                <sourceFile>project_swf_master_file.as</sourceFile>
            </configuration>
        </plugin>

        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <descriptors>
                        <descriptor>../master_build/swf-assembly.xml</descriptor>
                    </descriptors>
                </configuration>
                <executions>
                    <execution>
                        <id>WebContent-packaging</id>
                        <phase>package</phase>
                        <goals><goal>single</goal></goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>${group-id}</groupId>
            <artifactId>project_swc</artifactId>
            <version>${project.version}</version>
            <scope>${zefiro.swf.scope}</scope> <!-- tell Flex Mojo that we want to compile using runtime shared libraries (rsl) -->
            <type>swc</type>
        </dependency>
        [...]
    </dependencies>

</project>

It is my understanding that each POM file generates one target file (specified with the packaging tag) and that when using the Flex mojo this needs to be of format swf or swc. I seem to be unable to specifiy multiple targets here and also struggled to get my resource files included (Flex copy-resources copies the html wrapper which I don't need (for each project), the normal resource tag copies the resources, but don't packages them). What is now my current working version is to specify an own assembly descriptor which bundles my target .swf file together with the WebContent/ folder into a zip file. Maven has support for jar/war/bin files, but those seem to expect certain conditions to be true, which don't apply for my Flex projects (e.g. I don't have a web.xml)

swf-assembly.xml:

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
    <id>WebContent</id>
    <formats>
        <format>zip</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <fileSets>
        <!-- Take the base swf artifact (only, not the other stuff which is generated there) -->
        <fileSet>
            <directory>${project.build.directory}</directory>
            <outputDirectory>/</outputDirectory>
            <includes>
                <include>*.swf</include>
            </includes>
        </fileSet>
        <!-- add the WebContent folder -->
        <fileSet>
            <directory>FCPContent</directory>
            <outputDirectory>/</outputDirectory>
        </fileSet>
    </fileSets>
</assembly>

Now I've got the target directory with both the .swf file alone and a zip file containing my .swf file together with my WebContent/ resources. It's also placed in the Nexus repository upon calling 'mvn install', so this looks like a good step forward. Though I'm happy to do it completely different if that's better, as my final goal is to have a single directory (or zip/war file containing it) with some static files in it (our html wrapper and loader swf + configuration.xml), and for each of our swf projects (modules we load at runtime) a directory containing the .swf files and the WebContent/ resources - i.e. the contents of the zip files I'm now able to create for each project.

index.html
loader.swf
config.xml
project_swf/SampleProjectModule1.swf
project_swf/assets/labels.xlf
project_swf/config/config.xml
project2_swf/module2.swf
project2_swf/cool_colors_stylesheet.swf

So my question would be: how do define such a Maven master project which creates the final assembly in this format? If there's no other way, a working ANT file might be acceptable, though I've read that it Maven urges us to stay away from those hacks :)

I also need to compile stylesheet files which are then additional artifacts for the swf projects. I'll post a separate question for this.

解决方案

My solution is a bit complex and feels 'dirty' - I thought there could be a cleaner way, but at least I've got it running now.

Basically, I'm using the Maven-assembly-plugin to create intermediate zip archives ('war' does work equally well) containing the swf executable along with any necessary static assets for each plugin I'm creating (we're using an OSGi-like dynamic loader similar to how Eclipse works, one of the static files is a plugin.xml, others are translation files, none of them can be embedded into the .swf). Maven stores the .swf file in Maven filename notation as primary artifact - which I'm completely disregarding - and my zip archive (with the .swf name according to the finalName tag) alongside. The POM and assembly file for this works as shown in my original question.

I've added a blank assembly project which has the sole goal of depending on and thus including all of my other projects. The output of this project is my final, 'real' artifact, which I can then use for distribution and deployment. Since I didn't want to cluster my Eclipse workspace with too many helper projects I broke the 1:1 relationship of Maven projects and Eclipse projects: my Maven assembly plugin just lives in a subdirectory 'assembly' inside my master_build project. I added a module statement for it in my master pom (master_build/pom.xml) which will be executed in the reactor as last project. (Ordering is done automatically due to dependencies given - if you specify it as first module and it's not executed last, then you're building projects you don't need :)

I also made my assembly projects POM a child of my master POM. This is not necessary, but by doing so I can inherit the Maven properties I've defined. It also inherits the call to the Flex compiler, though since there is nothing to compile here this doesn't harm. YMMV.

Here's the POM:

<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>de.zefiro.maven.example</groupId>
        <artifactId>full_build</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../</relativePath>
    </parent>


    <groupId>${group-id}</groupId>
    <artifactId>full_assembly</artifactId>
    <name>Final Assembly</name>
    <version>${project.parent.version}</version>
    <packaging>pom</packaging> <!-- note that this is POM here, not war or zip -->

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.2.1</version>
                <configuration>
                    <descriptors>
                        <descriptor>final-assembly.xml</descriptor>
                    </descriptors>
                </configuration>
                <executions>
                    <execution>
                        <id>Final-Packaging</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>de.zefiro.maven.example</groupId>
            <artifactId>wrapper</artifactId>
            <version>1.0</version>
            <type>war</type>
        </dependency>
        <dependency>
            <groupId>${group-id}</groupId>
            <artifactId>project_swf</artifactId>
            <version>${project.version}</version>
            <type>zip</type>
            <classifier>WebContent</classifier> <!-- needs to be the ID of the assembler xml which packaged the zip file -->
        </dependency>
[... all other projects which should be packaged ...]
    </dependencies>
</project>

Following the assembly descriptor. See the assembly descriptor documentation for details.

<assembly
    xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
    <id>FinalAssembly</id>
    <formats>
        <format>war</format> <!-- can be either zip or war, depending on what you wish -->
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <dependencySets>
        <dependencySet>
            <includes>
                <include>de.zefiro.maven.example:wrapper:war:*</include>
            </includes>
            <unpack>true</unpack>
        </dependencySet>
        <dependencySet>
            <includes>
                <include>${group-id}:project_swf:zip:WebContent:${project.version}</include>
            </includes>
            <useProjectAttachments>true</useProjectAttachments>
            <unpack>true</unpack>
            <outputDirectory>sample_project_1</outputDirectory>
        </dependencySet>
[... list the same projects as in the POM file ...]
    </dependencySets>
</assembly>

I've got one archive which I'm just consuming, coming from a different department. It contains the HTML wrapper and the main Flex application which is run (and later loads all my plugins from the subdirectories according to a configuration file and the individual projects plugin.xml metadata). This is placed in the output archive root directory. All other projects are the ones I've created myself and get placed in individual subdirectories, thus I'm not using wildcards here. Since I want a single archive containing all files merged I use the unpack option of the dependencySet.

Note that the ID declared in the asembly descriptor for the individual swf plugin projects is now used as a classifier in the dependency section of the pom file as well as a part of the Maven location in the assembly descriptor. Same for the packacking type, which I've choosen zip here. Since this is only used for the intermediate archives, zip is fine, for the final assembly a different format can be chosen.

Inheriting from the same parent I can reuse my Maven properties, which are also available in the assembly descriptor.

A new project can be added by duplicating an existing project and adding it to:

  • master_build/pom.xml as a module
  • master_build/assembly/pom.xml in the dependencies section
  • master_build/assembly/final-assembly.xml as a dependencySet

The final artifact is a war file containing:

sample_project_1/SampleProjectModule1
sample_project_1/assets/labels.xlf
sample_project_1/config/config.xml
other_data/configuration.xml
application.swf
index.html

I.e. the contents of all my swf projects in their respective subdirectories merged with the contents of my wrapper.war containing the static files.

It can be retrieved from the repository at this location:

de.zefiro.maven.example:full_assembly:war:FinalAssembly:1.0-SNAPSHOT

To compile stylesheets for each plugin I'm using the same basic idea moved down to an individual project level. I'll describe it in the other questions

Open Issue: I cannot produce both debug and ship versions of the files. I could either double the projects and package them together (like I do with my stylesheets) or I could run the entire Maven reactor (for the parent POM and master assembly) twice, with e.g. different groupIds, and thus create two completely separate paths for all involved projects. I've not investigated further on this, though.

这篇关于使用 Maven 构建复杂的 Flex 项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆