我目前正在考虑用 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 项目有点不知所措。
我的项目的基本结构:
我的 swf 项目的布局:
我使用平面层次结构在 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 属性,这些属性也在程序集描述符中可用。
可以通过复制现有项目并将其添加到以下项目来添加新项目:
最后的 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/