Используйте Maven для создания сложного проекта Flex - PullRequest
5 голосов
/ 18 марта 2011

В настоящее время я пытаюсь заменить нашу очень проприетарную среду сборки на Maven. Текущее решение является внутренней разработкой для центральной сборки, и для облегчения локальной разработки я компилирую в Eclipse / Flex IDE и имею сценарий ANT, который копирует все вместе в мой локальный каталог Apache (т.е. мой файл ant не выполняет полную сборку а также полагается на то, что все проекты доступны локально).

Мы используем Eclipse 3.6.1 (Helios) с плагином Flash Builder (т. Е. Flex4), ориентируясь на Flex SDK 3.5 (FlashPlayer 10.0) с целым рядом проектов, как библиотечных проектов .swc, так и модулей .swf, загружаемых во время выполнения, включая ресурсы для каждого. Мы также используем внешние разделяемые библиотеки / библиотеки времени выполнения (с одним большим sharedlibraries.swf, имеющим все внутри, т.е. нет необходимости иметь файлы .swc при развертывании). Я установил Maven 3.0.2, используя Sonatypes flexmojos-maven-plugin 3.7.1 (так как он кажется более активным, чем у Servebox). Я вручную создал pom-файлы для каждого проекта Eclipse, чтобы убедиться, что все работает, а также в интеграции Eclipse-Maven отсутствует поддержка Flex. Я определил соответствующие параметры компилятора и зависимости, чтобы все отдельные проекты компилировались правильно - то есть результирующие файлы .swf действительно создают рабочую версию нашего приложения. Я также прочитал книгу « Maven by Example » от Sonatype и посмотрел на их « Maven: полный справочник », параллельно выполняя множество попыток поиска в Google.

С чем я борюсь, так это с окончательной сборкой моего проекта, а также с дополнительными артефактами (таблицами стилей). Я не совсем понимаю «путь 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 / каталог с дополнительными файлами, которые необходимо дословно скопировать в целевой артефакт (каталог или zip-файл) вместе с артефактом .swf
  • styles / Гибкие файлы .css, которые необходимо скомпилировать в файлы таблиц стилей .swf, это дополнительные артефакты (по одному на каждую .css для разных тем) для основного проекта swf и WebContent / содержание

Я использую плоскую иерархию для работы в 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 с использованием этого 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>

Затем я могу скомпилировать свои проекты библиотеки 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 и zip-файл, содержащий мой файл .swf вместе с моим WebContent / resources,Он также помещается в репозиторий Nexus после вызова 'mvn install', так что это выглядит как хороший шаг вперед.Хотя я рад сделать это совершенно по-другому, если это лучше, так как моя конечная цель - создать один каталог (или содержащий его файл zip / war) с некоторыми статическими файлами (наш html-упаковщик и загрузчик swf + configuration.xml).) и для каждого из наших проектов swf (модули, которые мы загружаем во время выполнения) каталог, содержащий файлы .swf и WebContent / resources - т.е. содержимое 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.Я выложу отдельный вопрос для этого.

1 Ответ

1 голос
/ 30 марта 2011

Мое решение немного сложное и кажется «грязным» - я подумал, что может быть более чистый способ, но по крайней мере у меня это работает сейчас.

По сути, я использую Maven-сборочный плагин для создания промежуточных zip-архивов («война» работает одинаково хорошо), содержащий исполняемый файл swf вместе со всеми необходимыми статическими ресурсами для каждого создаваемого плагина (мы используем OSGi-подобный динамический загрузчик, аналогичный тому, как работает Eclipseодин из статических файлов - это plugin.xml, другие - файлы перевода, ни один из них не может быть встроен в .swf).Maven хранит файл .swf в обозначении имени файла Maven в качестве основного артефакта, который я полностью игнорирую, и мой zip-архив (с именем .swf в соответствии с тегом finalName).POM и файл сборки для этого работают, как показано в моем исходном вопросе.

Я добавил пустой проект сборки, единственной целью которого является зависимость и, следовательно, включение всех других моих проектов.Результатом этого проекта является мой последний, «настоящий» артефакт, который я затем могу использовать для распространения и развертывания.Поскольку я не хотел кластеризовать свою рабочую область Eclipse со слишком большим количеством вспомогательных проектов, я нарушил отношения 1: 1 проектов Maven и проектов Eclipse: мой плагин сборки Maven просто находится в подкаталоге «Assembly» внутри моего проекта master_build.Я добавил для него оператор модуля в свой главный pom (master_build / pom.xml), который будет выполняться в реакторе как последний проект.(Упорядочение выполняется автоматически из-за заданных зависимостей - если вы указываете его как первый модуль, а он не выполняется последним, тогда вы создаете проекты, которые вам не нужны:)

Я также сделал мои проекты сборки POM aдитя моего мастера ПОМ.Это не обязательно, но тем самым я могу наследовать определенные мной свойства Maven.Он также наследует вызов к компилятору Flex, хотя, поскольку здесь нет ничего для компиляции, это не повредит.YMMV.

Вот 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>

После дескриптора сборки.Подробнее см. Документацию дескриптора сборки 1013 *.

<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).Это помещается в корневой каталог выходного архива.Все остальные проекты - те, которые я создал сам и помещаю в отдельные подкаталоги, поэтому здесь я не использую подстановочные знаки.Поскольку я хочу, чтобы единый архив, содержащий все объединенные файлы, я использую опцию unpack для зависимого набора.

Обратите внимание, что идентификатор, объявленный в дескрипторе сборки для отдельных проектов плагинов swf, теперь используется в качестве классификатора в разделе зависимостей.файла pom, а также часть местоположения Maven в дескрипторе сборки.То же самое для типа упаковки, которую я выбрал здесь.Поскольку это используется только для промежуточных архивов, zip подходит для конечной сборки. Можно выбрать другой формат.

Наследуя от одного и того же родителя, я могу повторно использовать свои свойства Maven, которые также доступны в сборке.дескриптор.

Новый проект можно добавить, продублировав существующий проект и добавив его в:

  • master_build / pom.xml в качестве модуля
  • master_build / assembly/pom.xml в разделе зависимостей
  • master_build / assembly / final-assembly.xml как набор зависимостей

Последний артефакт - это файл войны, содержащий:

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

Т.е. содержимое всех моих проектов swf в соответствующих подкаталогах объединено с содержимым моего wrapper.war, содержащего статические файлы.

Его можно получить из репозитория по этому адресу:

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

Для компиляции таблиц стилей для каждого плагина я использую ту же базовую идею, перенесенную на уровень отдельного проекта.Я опишу это в другие вопросы

Открытая проблема: я не могу создать отладочную и отгрузочную версии файлов. Я мог бы либо удвоить проекты и упаковать их вместе (как я делаю с моими таблицами стилей), или я мог бы запустить весь реактор Maven (для родительского POM и мастер-сборки) дважды, например, с помощью. различные идентификаторы групп и, таким образом, создают два совершенно разных пути для всех вовлеченных проектов. Я не исследовал это дальше, хотя.

...