Flexmojos. Собираем AIR приложение.

Ну давайте разберемся как с помощью flexmojos собирать AIR приложение.

Создаем проект

Для начала создадим простенький проект такой структуры:

try-flexmojos
- src
  - main
    - flex
      - SimpleAirApp.mxml
    - resources
      - icons
        - icon_128.png
        - icon_48.png
        - icon_32.png
        - icon_16.png
      - descriptor.xml
- pom.xml

Главный класс приложения у нас будет незамысловатый:


<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication
		xmlns:fx="http://ns.adobe.com/mxml/2009"
		xmlns:s="library://ns.adobe.com/flex/spark"
        width="350" height="200">

	<s:VGroup width="100%" height="100%">
		<s:Label text="Hello World!"/>
		<s:Button label="Hello :)"/>
	</s:VGroup>

</s:WindowedApplication>

pom.xml сделаем одиночным и самодостаточным, без суперпома, без родительского и без дочерних помов, не использующим какие-либо настройки из .m2/settings.xml.


<?xml version="1.0" encoding="UTF-8"?>
<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>try-flexmojos</groupId>
	<artifactId>make-air-app</artifactId>
	<version>1.0</version>
	<packaging>swf</packaging>

	<properties>
		<flexmojos.version>3.8-de0</flexmojos.version>
		<fdk.version>4.1.0.15885</fdk.version>
		<fp.version>10.0.42</fp.version>
	</properties>

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

		<plugins>
			<plugin>
				<groupId>org.sonatype.flexmojos</groupId>
				<artifactId>flexmojos-maven-plugin</artifactId>
				<executions>
					<execution>
						<id>pack</id>
						<phase>package</phase>
						<goals>
							<goal>sign-air</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
					<!-- NOTE: you can set keystore and storetype other than default
					<keystore>/home/yura/p/flexmojos-air/src/main/resources/sign.p12</keystore>
					<storetype>pkcs12</storetype>
					-->
					<storepass>iampass</storepass>
				</configuration>
			</plugin>
		</plugins>

		<pluginManagement>
			<plugins>
				<plugin>

					<groupId>org.sonatype.flexmojos</groupId>
					<artifactId>flexmojos-maven-plugin</artifactId>
					<version>${flexmojos.version}</version>
					<extensions>true</extensions>

					<dependencies>
						<dependency>
							<groupId>com.adobe.flex</groupId>
							<artifactId>compiler</artifactId>
							<version>${fdk.version}</version>
							<type>pom</type>
						</dependency>

						<dependency>
							<groupId>com.adobe.flex.compiler</groupId>
							<artifactId>asdoc</artifactId>
							<version>${fdk.version}</version>
							<type>zip</type>
							<classifier>template</classifier>
						</dependency>

						<dependency>
							<groupId>com.adobe.flex</groupId>
							<artifactId>adt</artifactId>
							<version>4.0.0.15885</version>
						</dependency>

					</dependencies>

					<configuration>
						<debug>true</debug>
						<targetPlayer>${fp.version}</targetPlayer>
						<warnings>
							<noConstructor>false</noConstructor>
						</warnings>
					</configuration>

				</plugin>
			</plugins>
		</pluginManagement>
	</build>

	<dependencies>

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

		<!--
		NOTE: do not use these dependencies for AIR application
		<dependency>
			<groupId>com.adobe.flex.framework</groupId>
			<artifactId>flex-framework</artifactId>
			<version>${fdk.version}</version>
			<type>pom</type>
		</dependency>

		<dependency>
			<groupId>com.adobe.flex.framework</groupId>
			<artifactId>playerglobal</artifactId>
			<version>${fdk.version}</version>
			<classifier>10</classifier>
			<type>swc</type>
		</dependency>
		-->

		<dependency>
			<groupId>com.adobe.flexunit</groupId>
			<artifactId>flexunit</artifactId>
			<version>4.0-rc-1.1</version>
			<type>swc</type>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>com.adobe.flexunit</groupId>
			<artifactId>uiRunner</artifactId>
			<version>4.0-rc-1.1</version>
			<type>swc</type>
			<scope>test</scope>
		</dependency>

	</dependencies>

	<repositories>

		<repository>
			<id>flex-mojos-repository</id>
			<url>http://repository.flyti.org/</url>
			<releases>
				<enabled>true</enabled>
			</releases>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>

	</repositories>

	<pluginRepositories>

		<pluginRepository>
			<id>flex-mojos-repository</id>
			<url>http://repository.flyti.org/</url>
			<releases>
				<enabled>true</enabled>
			</releases>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</pluginRepository>

	</pluginRepositories>

</project>

Некоторые моменты в этом pom я прокомментирую:

  • Используется форк develar версия 3.8-de0 (более ранние версии работают неправильно!).
  • Подключен только репозиторий http://repository.flyti.org/ где всеми артефактами управляет develar :)
  • Главная зависимость, это com.adobe.flex.framework:air-framework.
  • Зависимости com.adobe.flex.framework:flex-framework и com.adobe.flex.framework:playerglobal указывать не нужно (а если укажете, то не соберется).
  • Еще одна очень важная зависимость, это com.adobe.flex:adt -- тул, который будет паковать AIR архив. Это коммерческий компонент и из-за лицензионных ограничений его не включают в публичные репозитории, но в репозитории develar он есть. А если вы используете стандартный репозиторий, то вам придется установить этот компонент вручную, командной mvn install:install-file.
  • Присутствует goal:sign-air, где и происходит генерация и подписка AIR-файла.

Теперь можно запускать mvn compile, любоваться BUILD SUCCESSFUL и лицезреть make-air-app-1.0.swf в папке target.

Запускаем swf и убеждаемся, что он работает

Прежде, чем двигаться дальше, хотелось бы запустить этот swf и поглядеть, как он работает. Во флэш плеере это не запустишь, но можно воспользоваться утилитой adl (Air Debug Launcher), входящей в состав AIR SDK.

Чтобы понять, как им пользоваться, нужно прочитать Using the AIR Debug Launcher (ADL)

Я запускаю swf таким скриптом:
run_with_adl.sh


#!/bin/bash

/home/yura/dev/AdobeAIRSDK/bin/adl \
-runtime /home/yura/dev/AdobeAIRSDK/runtimes/air/linux \
src/main/resources/descriptor.xml target/

Но сперва нам понадобится descriptor.xml


<?xml version="1.0" encoding="utf-8" ?>
<application
		xmlns="http://ns.adobe.com/air/application/2.0">

	<id>try-flexmojos.make-air-app</id>
	<filename>SimpleAirApp</filename>
	<name>Simple Air App</name>
	<version>1.0</version>

	<initialWindow>
		<title>Simple Air App</title>
		<!--<content>${output}</content>-->
		<content>make-air-app-1.0.swf</content>
	</initialWindow>
	
	<icon>
		<image16x16>icons/icon_16.png</image16x16>
		<image32x32>icons/icon_32.png</image32x32>
		<image48x48>icons/icon_48.png</image48x48>
		<image128x128>icons/icon_128.png</image128x128>
	</icon>
	
</application>

Обратите внимание, что в дескрипторе указаны 4 иконки, которые находятся в проекте в src/main/resources/icons.

Итак, swf запускается и работает.

Кто-нибудь скажет, что автор -- замороченный линуксоид, и нафиг эти скрипты и adl, а надо все из IDE запускать. Действительно надо, особенно если мы хотим не просто один раз запустить, а разрабатывать и отлаживать приложение.

Поэтому расскажу, как это дело запускать в Intellij IDEA. Вообще-то я изначально создавал проект в IDEA. Но если бы это было не так, то IDEA может открыть pom.xml как проект, после чего нужно запустить mvn compile -DconfigurationReport=true, и готово, проект поднят.

Теперь находим SimpleAirApp.mxml, правый клик на нем, в контекстном меню выбираем Create "SimpleAirApp" и попадаем в диалог Create Run/Debug Configuration.

IDEA нам предлагает указать AIR application descriptor или сгенерировать его автоматически (по умолчанию). Дескриптор у нас есть, так что укажем (долго искать его по файловой системе не придется, IDEA достаточно умна, чтобы самой найти его в проекте). Остальное оставляем по умолчанию. Apply. OK.

У нас появился Run Configuration. Жмем Run или Debug, и вуаля -- оно не работает :). Потому что в параметрах запуска, внезапно, -runtime /home/yura/dev/flex_sdk_4.0.0.14159/runtimes/air/mac. А у нас вовсе и не mac, а очень даже linux.

Ну не беда. Открываем Project Structure -> SDKs -> compiler-4.0.0.14159.pom. Находим настройки AIR Debug Launcher и AIR Runtime. Так, adl у нас есть во Flex SDK, а вот AIR Runtime там нету (есть только для mac и для win). Тогда скачиваем AIR SDK, распаковываем, и указываем в проекте настройки:

AIR Debug Launcher: /home/yura/dev/AdobeAIRSDK/bin/adl

AIR Runtime: /home/yura/dev/AdobeAIRSDK/runtimes/air/linux

Вот теперь swf запускается и дебажится как надо.

Собираем AIR-архив

Итак, нам нужно создать AIR-архив, который является инсталлятором нашего приложения. AIR-архив представляет собой zip-архив, содержащий swf-файл, метаданные и ресурсы (иконки и прочее). Этот архив подписывается сертификатом, что позволяет идентифицировать производителя приложения (вас).

Правильный сертификат покупается за деньги у специальных вендоров. И если вы это сделаете, то инсталлятор вашего AIR приложения расскажет пользователю, что вы респектабельный производитель, которому можно доверять.

Неправильный сертификат можно сгенерировать самому. В этом случае инсталлятор вашего AIR приложения расскажет пользователю, что приложение сделал невесть кто невесть откуда, и пусть он, пользователь, устанавливает это на свой страх и риск.

В любом случае без сертификата инсталлятор создать нельзя.

Для генерации сертификата и создания инсталлятора используется утилита adt (Air Developer Tool), которая входит в состав Flex SDK и AIR SDK. Документация по использованию adt здесь: Packaging an AIR installation file using the AIR Developer Tool (ADT)

Генерируем сертификат:
generate_certificate.sh


#!/bin/bash

/home/yura/dev/AdobeAIRSDK/bin/adt \
-certificate -cn SelfSigned 1024-RSA \
src/main/resources/sign.p12 iampass

Файл сертификата можно назвать как угодно, но flexmojos по умолчанию использует имя sign.p12 и ищет сертификат в папке resources. Так что именно так мы и генерируем. После запуска этого скрипта у нас появляется файлик src/main/resources/sign.p12.

Если вы хотите держать сертификат в другом месте и с другим именем, или у него storetype отличается от умолчального pkcs12, то вам нужно указать это в пом.


<plugins>
	<plugin>
		<groupId>org.sonatype.flexmojos</groupId>
		<artifactId>flexmojos-maven-plugin</artifactId>
		<executions>
			<execution>
				<id>pack</id>
				<phase>package</phase>
				<goals>
					<goal>sign-air</goal>
				</goals>
			</execution>
		</executions>
		<configuration>
			<keystore>/path/to/your/sert/sign.p12</keystore>
			<storetype>pkcs12</storetype>
			<storepass>iampass</storepass>
		</configuration>
	</plugin>
</plugins>

Теперь запускаем mvn package. И, вуаля, получаем target/make-air-app-1.0.air. Если мы заглянем в этот архив, то увидим там make-air-app-1.0.swf, папку icons с четырьмя иконками, и файлы с метаинформацией. Flexmojos кладет в архив все, что есть в папке resources, кроме сертификата и дескриптора.

Напоследок пара нюансов:

adt, когда подписывает файл сертификатом, юзает сервис реального времени. И ему для этого нужен инет. Так что запаковать AIR файл будучи оффлайн невозможно. Кроме того, оный сервис может по каким-то причинам не работать. И с этим я сталкивался. И приходилось с помощью опции -tsa задавать другой сервер, вместо дефолтного timestamp.geotrust.com

В descriptor.xml вы указываем <content>make-air-app-1.0.swf</content>. Очевидно, что при смене номера версии или имени swf файла эту строку нужно будет поправить. Но об этом легко забыть. Flexmojos позволяет сделать так <content>${output}</content> и таки забыть об этом. Об имени файла он позаботится сам. Но, конечно, если вы будете собирать баш-скриптом, то ${output} использовать нельзя.

И в качестве бонуса баш-скрипт, который пакует и подписывает инсталлятор из командной строки.

pack_air.sh


#!/bin/bash

cp src/main/resources/descriptor.xml target
cp -r src/main/resources/icons target
cd target

/home/yura/dev/AdobeAIRSDK/bin/adt \
-package -storetype pkcs12 \
-keystore ../src/main/resources/sign.p12 -storepass iampass \
make-air-app-1.0.air descriptor.xml make-air-app-1.0.swf icons

Проект можно скачать тут. Он должен работать как есть, прямо из коробки. Если вдруг у вас что-то не работает, плз, обязательно сообщите об этом.

Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
CAPTCHA
question for bots )
Image CAPTCHA
Enter the characters shown in the image.