eclipse - 使用 Maven 构建复杂的 Flex 项目

标签 eclipse apache-flex actionscript-3 maven sonatype

我目前正在考虑用 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-plugin 3.7.1 (因为它似乎比 Servebox 的更活跃)。我已经为每个 Eclipse 项目手动创建了 pom 文件,以确保一切正常,而且 Eclipse-Maven 集成似乎缺乏 Flex 支持。我已经定义了适当的编译器和依赖项参数,以便所有单独的项目都能正确编译 - 即生成的 .swf 文件确实会生成我们应用程序的工作版本。我还阅读了 Sonatype 的“Maven by Example”书并查看了他们的“Maven: The Complete Reference”,同时进行了大量的谷歌搜索。

我正在努力的是我的项目的最终组装,以及额外的 Artifact (样式表)。我不完全理解“Maven 方式”,也怀疑 Maven 是为 Java 量身定制的,因此让我对我的 Flex 项目有点不知所措。

我的项目的基本结构:

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

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

  • 我使用平面层次结构在 Eclipse 中工作,即我的主 pom 文件放置在一个文件夹中,该文件夹是所有项目文件夹的同级文件夹。例子:
    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
    

    我已经成功地使用此 创建了一个“主构建”来构建我所有的 swc 和 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/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>
    

    然后我可以编译我的 swc 图书馆项目 使用这个简单的 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>
    

    还有我的 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>
    
        <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>
    

    据我了解,每个 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>
        <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>
    

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

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

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

    最佳答案

    我的解决方案有点复杂,感觉很“脏” - 我认为可能有一种更清洁的方法,但至少我现在已经运行了。

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

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

    我还让我的装配项目 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>
    
        <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>
    

    在程序集描述符之后。见 assembly descriptor documentation详情。
    <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>
    

    我有一个来自不同部门的文件,我正在使用它。它包含 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 作为依赖集

  • 最后的 Artifact 是一个 war 文件,其中包含:
    sample_project_1/SampleProjectModule1
    sample_project_1/assets/labels.xlf
    sample_project_1/config/config.xml
    other_data/configuration.xml
    application.swf
    index.html
    

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

    可以从以下位置的存储库中检索它:
    de.zefiro.maven.example:full_assembly:war:FinalAssembly:1.0-SNAPSHOT
    

    为了为每个插件编译样式表,我使用了相同的基本思想,并将其移至单个项目级别。我会在 the other questions 中描述它

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

    关于eclipse - 使用 Maven 构建复杂的 Flex 项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5356523/

    相关文章:

    apache-flex - Flex 字典排序

    python - 使用 as3 打包/解包二进制数据

    ldpi,mdpi,hpdi的像素中的Android屏幕尺寸?

    c++ - 带有 CDT 的 Eclipse 3.7.0 Indigo 显示许多错误的编译错误

    android - 如何获取 Android 应用程序的 .apk 以在 Eclipse 中分发?

    apache-flex - Flex DataGridColumn id 丢失?

    java - 从 Java 类自定义 Granite DS Actionscript 代码生成

    eclipse : Using same output folder for different projects

    actionscript-3 - Flash 中的地理定位

    apache-flex - 如果我的 flex 数据网格是可编辑的,如何使我的一些数据网格列不可编辑或只读