Ну давайте разберемся как с помощью 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 я прокомментирую:
Теперь можно запускать mvn compile, любоваться BUILD SUCCESSFUL и лицезреть make-air-app-1.0.swf в папке target.
Прежде, чем двигаться дальше, хотелось бы запустить этот 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-архив представляет собой 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