Archiv für September 2008

26
Sep

Enia Product Evaluation & Celebration System

Heute war ein besonderer Tag. Nach mehreren Wochen Entwicklungszeit wurde das Enia Product Evaluation & Celebration System (ePEC) freigeschalten. Bei der Applikation handelt es sich um eine innovative Lösung zur Suche eines geeigneten Teppiches in der grossen Masse der Produkte von Enia. Das ganze Konzept wurde von Sensorial Surroundings erarbeitet und von mir bei ScreenConcept umgesetzt.

ePEC

Die verwendeten Technologien sind ContentServ für die Datenhaltung und Flex für das Frontend.

Ich hätte nie gedacht, dass ich eines Tages ein Projekt in Flash realisieren würde. Ehrlich gesagt fand ich bis anhin das Rumgefummel in Flash ziemlich unpraktikabel. Um so überraschter war ich, als ich den ersten Prototypen in Flex realisiert hatte: Die Eclipse basierte IDE Flex Builder ist ziemlich gut (bis auf ein paar kleine Details wie z.B. fehlendes Refactoring), der Source Code ist frei Verfügbar und steht unter der Mozilla Public License und eine aktive, hilfsbereite Entwicklergemeinschaft erleichtert den Einstieg. Das Framework ist sauber aufgebaut und schnell zu erlernen. Es überzeugt im ganzen und man ist ziemlich flink in der Entwicklung von RIA Applikationen.

Alles in allem war das ePEC ein ziemlich cooles Projekt mit viel Spass bei der Entwicklung: Anstatt Architektur durch diverse Layer wie früher bei grossen J2EE Projekten, wieder einmal im kleinen Denken: Zugriff auf einzelne Bits und die Farbraumtheorie fordert dann auch wieder eimal meine Mathekenntnisse. Anstatt zu Clustern um die Performance zu Verbessern, das letzte aus den Objekte herausholen und den Code optimieren. Zum Glück habe ich schon einige Jahre Assembler auf dem Buckel und Optimierungen dieser Art sind mir nicht ganz unbekannt.

Das nächste Flex Projekt befindet sich übrigens bereits schon in Arbeit - auch diesmal wieder etwas spannendes und einzigartiges. Sicher kann ich bald mehr darüber berichten…

03
Sep

Bedingte Flex 3 Kompilation mit Apache Ant

Seit einiger Zeit habe ich ein neues Spielzeug zum Arbeiten: Der Eclipse basierte Flex Builder 3 von Adobe ermöglicht einem Softwareentwickler einen einfacheren Einstieg in die Flash-Programmierung. Die IDE ist an sich ziemlich toll für die Entwicklung, ich vermisse im Moment einzig die Refactoring Werkzeuge aus der Java Welt - aber vielleicht kommt das ja bei der nächsten Version. Als Java Entwickler findet man ziemlich schnell den Einstieg in das gut dokumentierte Flex Framework, mit seinen logisch aufgebauten Komponenten. Auch ActionScript 3 bereitet keine grossen Schwierigkeiten und man kann sehr schnell loslegen und nach ein paar wenigen Stunden produktiv arbeiten. Anders als bei Flash wird mit mit Flex nicht Design- sondern Codezentriert entwickelt.

Für Ant liefert Adobe die Flex Ant Tasks mit, womit man in gewohnter Java-Manier Projekte bauen und auch bedingt kompilieren und konfigurieren kann - davon handelt dieser Artikel.

Für die Installation müssen als erstes mit dem Eclipse Software Update die Java Development Tools installiert werden, womit man die Ant Laufzeitumgebung und auch eine graphische Ant Ansicht bekommt. In der nachfolgenden Build-Datei muss eventuell lediglich der Pfad zu den Ant-Tasks angepasst werden. Dies kann man auch alternativ in den Einstellungen von Eclipse unter “Ant > Runtime” machen, indem man die flexTasks.jar in den Klassenpfad einbindet.

Das Ergebniss der nachfolgenden Anleitung kann am Ende des Artikels als Archiv heruntergeladen werden.

Als erster Schritt legen wir im Flex Builder ein neues Projekt ’sample’ an und erstellen ein Verzeichniss build, wo alle Build relevanten Dateien ihr Zuhause finden. Als wohl wichtigste Datei wird die build.xml angelegt und anschliessen in die Ant Ansicht von Eclipse gezogen.

Eine minimale Datei kann wie folgt aussehen:


<project default="compile_test" basedir="..">

	<!-- load the property file -->
	<property file="build/build.properties" />

	<!-- define the flex ant tasks -->
	<taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar" />

	<!-- ************************************************ -->
	<!-- clean all generated files and folders -->
	<!-- ************************************************ -->
	<target name="clean" description="Clean all build assets">
		<echo message="Deleting all artefacts"/>

		<!-- clean apps -->
		<delete dir="${output.folder}"/>

		<!-- clean incremental cache -->
		<delete file="${basedir}/src/*.cache"/>
	</target>

	<!-- ************************************************ -->
	<!-- Compile sample application for test -->
	<!-- ************************************************ -->
	<target name="compile_test" description="Compiles the sample application for test">

		<echo message="Compile sample application for test"/>

		<mkdir dir="${output.folder}/test"/>

		<antcall target="compile">
			<param name="OUTPUT_NAME" value="test/sample.swf"/>
			<param name="FLEX_CONFIG" value="${basedir}/build/flex-config-test.xml"/>
		</antcall>
	</target>

	<!-- ************************************************ -->
	<!-- Compile sample application for production -->
	<!-- ************************************************ -->
	<target name="compile_prod" description="Compiles the sample application for production">

		<echo message="Compile sample application for production"/>

		<mkdir dir="${output.folder}/prod"/>

		<antcall target="compile">
			<param name="OUTPUT_NAME" value="prod/sample.swf"/>
			<param name="FLEX_CONFIG" value="${basedir}/build/flex-config-prod.xml"/>
		</antcall>
	</target>

	<!-- ************************************************ -->
	<!-- compile the flex application -->
	<!-- ************************************************ -->
	<target name="compile">

            <echo message="Compile with config: ${FLEX_CONFIG}"/>

            <mxmlc file="${basedir}/src/sample.mxml"
                   output="${output.folder}/${OUTPUT_NAME}"
                   actionscript-file-encoding="UTF-8"
                   keep-generated-actionscript="false"
                   incremental="true">

                <!-- get default compiler options -->
                <load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>
                <load-config filename="${FLEX_CONFIG}"/>

                <!-- include sources -->
                <source-path path-element="${FLEX_HOME}/frameworks"/>
                <source-path path-element="${basedir}/src"/>

                <!-- include libraries -->
                <compiler.library-path dir="${FLEX_HOME}/frameworks" append="true">
	                <include name="libs" />
                </compiler.library-path>
            </mxmlc>

	</target>

</project>

Das scheint ziemlich viel XML zu sein, aber auf den zweiten Blick ist das nur halb so wild. Die Build-Datei ist in folgende Aktionen aufgesplittet:

  • clean - löscht den Ordner wo das SWF hineingeneriert wird und auch den Zwischenspeicher für die inkrementelle Kompilation
  • compile_test - Ruft die Kompilation mit den Parametern für die Testumgebung auf
  • compile_prod - Ruft die Kompilation mit den Parametern für die Produktivumgebung auf
  • compile - hier wird die Applikation mit dem MXMLC Kompiler übersetzt

Im Script selber werden einige Variabel gebraucht, welche man pro Rechner anpassen muss. Ich mache die meistens so, indem ich im Source-Repository ein build.properties.sample mit Beispielvorgaben abspeichere, welche dann von jedem Entwickler angepasst und unter build.properties gespeichert werden muss.

Hier ein Beispiel:


FLEX_HOME=/Applications/Adobe Flex Builder 3/sdks/3.0.0
APP_ROOT=src
output.folder=apps

Also einfach FLEX_HOME anpassen und schon ist der erste Teil des Build-Systemes bereit und die Ant-Datei kann in der Ant-View in Eclipse geöffnet werden:

Picture 2.png

Bevor wir uns aber ans erste Kompilieren machen, sollten wir noch die Konfigurationen für die unterschiedlichen Systeme anlegen. Diese wird in Form einer XML-Datei im build Ordner gemacht:

flex-config-test.xml


<?xml version="1.0" encoding="UTF-8"?>
<flex-config>
	<compiler append="true">
		<debug>true</debug>
	    <define>
	        <name>CONFIG::text</name>
	        <value>'Testing'</value>
	    </define>
	    <define>
	        <name>CONFIG::button</name>
	        <value>true</value>
	    </define>
	</compiler>
</flex-config>

flex-config-prod.xml


<?xml version="1.0" encoding="UTF-8"?>
<flex-config>
	<compiler append="true">
		<debug>true</debug>
	    <define>
	        <name>CONFIG::text</name>
	        <value>'Production'</value>
	    </define>
	    <define>
	        <name>CONFIG::button</name>
	        <value>false</value>
	    </define>
	</compiler>
</flex-config>

Natürlich können wir auch für den Flex Builder eine Konfigurationsdatei anlegen, ich nenne diese flex-config-local.xml. Diese Datei wird dann für die lokale Kompilation im Flex Builder verwendet.

flex-config-local.xml


<?xml version="1.0" encoding="UTF-8"?>
<flex-config>
	<compiler append="true">
		<debug>true</debug>
	    <define>
	        <name>CONFIG::text</name>
	        <value>'Local Development'</value>
	    </define>
	    <define>
	        <name>CONFIG::button</name>
	        <value>true</value>
	    </define>
	</compiler>
</flex-config>

Diese Datei müssen wir noch in den Projekt-Einstellungen eintragen, und zwar beim Flex Kompilers um ‘-load-config+=../build/flex-config-local.xml’ als zusätzliches Argument anhängen:

config-local

Somit lässt sich bereits ein kleines Beispiel erstellen und kompilieren, welches von der bedingten Kompilation gebrauch macht. Dazu legen wir die Datei src/sample.mxml mit folgendem Inhalt an:


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="init();">
	<mx:Script source="sample.as"/>
	<mx:Label x="10" y="10" text="{TEXT}"/>
	<mx:Button id="theButton" x="10" y="36" label="Button"/>
</mx:Application>

Zuletzt kommt noch die Actionscript 3 Datei src/sample.as hinzu:


[Bindable]
public static var TEXT:String = CONFIG::text;

private function init():void {
	if (!CONFIG::button) {
		theButton.visible = false;
	}
}

Der Trick an der ganzen Sache ist recht einfach: Man kann auf die Deklarationen in den Konfigurationsdateien einfach zugreifen, z.B. mit…

  • CONFIG::text - Holt den String aus der Konfigurationsdatei (WICHTIG: ein String muss in der Datei immer mit Hochkommatas umschlossen sein - hat mich einige Stunden gekostet!)
  • CONFIG::button - wertet das Boolean aus

Des weiteren ist es auch möglich, ganze Klassen auszutauschen. Die Englische Dokumentation zur bedingten Kompilation findet sich in Adobe’s Flex 3 Hilfe.

Ausserdem kann man weitere Kompileroptionen wie Netzzugriff und Metadaten in der Konfigurationsdatei einbinden. Hier ein paar Beispiele für Einstellungen welche ist bereits verwendet habe:

Debug Informationen in das SWF Kompilieren:


<debug>true</debug>

Netzwerkzugriff ein- bzw. ausschalten. Mit ausgeschaltetem Netzwerkzugriff kann man auch lokal Daten lesen. Die kann für die Erstellung einer Flex Offline Applikation nützlich sein (Ich weiss es gibt AIR, kann aber trotzdem manchmal passend sein):


<use-network>true</use-network>

Metadaten einbinden:


<metadata>
    <title>Sample</title>
    <description>Sample Flex Application</description>
    <publisher>Netzpiraten</publisher>
    <creator>Michael Kessler</creator>
</metadata>

Die Beispiel-Applikation sieht nun folgendermassen aus, wenn man sie direkt aus dem Flex Builder heraus startet:

Picture 3.png

In einem weiteren Schritt kompilieren wir die Applikation mit Ant, indem wir ‘compile-test‘ aufrufen. Die Ausgabe in der Konsole sollte etwa so sein:


Buildfile: /Users/michi/Documents/Flex Builder 3/sample/build/build.xml
compile_test:
     [echo] Compile sample application for test
compile:
     [echo] Compile with config: /Users/michi/Documents/Flex Builder 3/sample/build/flex-config-test.xml
    [mxmlc] Loading configuration file /Applications/Adobe Flex Builder 3/sdks/3.0.0/frameworks/flex-config.xml
    [mxmlc] Loading configuration file /Users/michi/Documents/Flex Builder 3/sample/build/flex-config-test.xml
    [mxmlc] /Users/michi/Documents/Flex Builder 3/sample/src/sample_363677.cache (No such file or directory)
    [mxmlc] /Users/michi/Documents/Flex Builder 3/sample/apps/test/sample.swf (250033 bytes)
BUILD SUCCESSFUL
Total time: 8 seconds

Die Applikation liegt nun unter /apps/test/sample.swf und sieht folgendermassen aus, wenn man diese in einen Webbrowser zieht:

Picture 5.png

Das gleiche Prozedere mit ‘compile-prod‘:

Picture 4.png

Wenn alles geklappt hat, sollten bei dir nun folgende Ordner und Dateien im Flex Builder sein:

Picture 6.png

Prima. Klappt ja alles Bestens! Letztendlich kann das Projekt nun auch sehr einfach in einen kontinuierlichen Buildprozess eingebunden werden, z.B. mit Hudson oder CruiseControl.

Ein weiteres Zückerlein ist ein einfaches aber effektives SSH Deployment. Dazu wird die jsch Bibliothek benötigt, welche man herunterladen und in den Klassenpfad einbinden muss. Dannach muss die Ant-Datei lediglich um ein paar Zeilen erweitert werden:


<!-- ************************************************ -->
<!-- deploy the online version -->
<!-- ************************************************ -->
<target name="deploy_test" depends="clean,compile_test" description="Deploy the sample application to the test system">
	<echo message="Deploy sample application to test system"/>
	<scp file="${output.folder}/test/sample.swf" todir="/var/www/sample/" keyfile="${user.home}/.ssh/id_rsa" passphrase=""/>
</target>

Hat man eine passwortlose Anmeldung mittels einer SSH Public-Key-Authentifizierung eingerichtet, ist das Deployment einer neuen Version auf ein System nur einen Doppelklick entfernt.

Die Beispielapplikation kann übrigens hier heruntergeladen werden: Flex Ant Sample (330)

Happy Building & Deploying!




September 2008
M D M D F S S
« Aug   Okt »
1234567
891011121314
15161718192021
22232425262728
2930  

Werbung


Buttonitis