<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>La Fabrick &#187; Java</title>
	<atom:link href="http://www.lafabrick.com/blog/tag/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.lafabrick.com/blog</link>
	<description>Laboratoire d&#039;interfaces riches (Flex, Flash, Air ...)</description>
	<lastBuildDate>Mon, 28 Nov 2011 22:02:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.4</generator>
		<item>
		<title>ORM, Hibernate et contrariétés&#8230;</title>
		<link>http://www.lafabrick.com/blog/2011/02/26/2429-orm-hibernate-et-contrarietes/</link>
		<comments>http://www.lafabrick.com/blog/2011/02/26/2429-orm-hibernate-et-contrarietes/#comments</comments>
		<pubDate>Sat, 26 Feb 2011 10:30:59 +0000</pubDate>
		<dc:creator>Hervé</dc:creator>
				<category><![CDATA[[Dev] Flash / Flex / AIR...]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[LINQ]]></category>
		<category><![CDATA[ORM]]></category>

		<guid isPermaLink="false">http://www.lafabrick.com/blog/?p=2429</guid>
		<description><![CDATA[&#160; L’ORM, Object-Relational-Mapping ou, dans la langue de Molière (ou presque), Mapping Objet Relationnel est un concept en vogue depuis longtemps, choisi par les équipes d’architectes techniques de tous poils, préconisé par des consultants de tous horizons.&#160; Après quelques années à développer des « applications d’entreprise », j’ai eu l’occasion d’aboutir un constat : pourquoi [...]]]></description>
			<content:encoded><![CDATA[<p style="float: left; margin-right: 10px;">&nbsp;</p>
<div>L’ORM, Object-Relational-Mapping ou, dans la langue de Molière (ou presque), Mapping Objet Relationnel est un concept en vogue depuis longtemps, choisi par les équipes d’architectes techniques de tous poils, préconisé par des consultants de tous horizons.&nbsp;</p>
<p>Après quelques années à développer des « applications d’entreprise », j’ai eu l’occasion d’aboutir un constat : pourquoi se compliquer la vie avec un ORM quand on peut faire plus simple, plus rapide et au moins aussi maintenable ?</p>
<p>Cet article est une occasion de partager cette analyse avec vous, et (re)déclencher un vieux débat sur lequel je n’ai que rarement eu l’occasion de consulter des discussions en français.</p>
</div>
<p><span id="more-2429"></span></p>
<h2>Rappel : qu’est-ce qu’un ORM ?</h2>
<p>Un ORM fonctionne sur la base d’ajout de méta-données décrivant une correspondances entre des tables et colonnes de base de données et des objets et leurs propriétés.</p>
<p>Concrètement, un utilisateur pourra être modélisé par une classe</p>
<pre class="brush: java">

public class User

{
private int id;
private String nom;
private String prenom;
// Getters et setters
}
</pre>
<p>Les méta-données pouvant ressembler globalement à ça :</p>
<pre class="brush: xml">

&lt;mapping&gt;

&lt;class name=&quot;User&quot; table=&quot;USER_TABLE&quot;&gt;

&lt;property name=&quot;id&quot; column=&quot;USER_ID&quot; /&gt;

&lt;property name=&quot;nom&quot; column=&quot;USER_LASTNAME&quot; /&gt;

&lt;property name=&quot;prenom&quot; column=&quot;USER_FIRSTNAME&quot; /&gt;

&lt;/class&gt;

&lt;/mapping&gt;
</pre>
<p><em>Attention à ne pas considérer cet exemple comme fonctionnel il permet uniquement de se faire une idée du principe.</em></p>
<p>Une fois cette configuration effectuée, vous pouvez ensuite travailler avec un gestionnaire d’entité qui prendra automatiquement en charge la persistance de votre objet au sein de la base de données que vous utilisez.</p>
<p>Concrètement, ce gestionnaire d’entité travaille avec un pool d’objets, souvent appelé «cache de premier niveau», qui contient des objets récupérés de la base de données. Il propose pour cela des fonctions type :</p>
<ul>
<li><strong>save</strong></li>
<li><strong>queryForObject</strong></li>
<li><strong>queryForList</strong></li>
<li><strong>merge</strong></li>
<li>&#8230;</li>
</ul>
<p>pour sauvegarder / récupérer des éléments dont le mapping a été défini, ou intégrer des objets au cache de premier niveau.</p>
<p>L’autre fonctionnalité très prisée d’un ORM concerne la modélisation des relations entre les objets et donc les tables. Vous pouvez effectivement indiquer que votre utilisateur dispose de profils et ce profil de rôles.</p>
<p>Vous aboutirez à un modèle de type :</p>
<p><a href="http://www.lafabrick.com/blog/wp-content/uploads/2011/02/ORM-Modèle.png"><img class="aligncenter size-full wp-image-2434" title="Modele de données pour ORM" src="http://www.lafabrick.com/blog/wp-content/uploads/2011/02/ORM-Modèle.png" alt="Modele de données pour ORM" width="595" height="237" /></a></p>
<p>Il est alors possible de modéliser ces relations dans les méta-données et déclarer des propriétés supplémentaires dans notre classe. Par exemple, la classe User se verra ajouter</p>
<pre class="brush: java">

private List&lt;Profile&gt; profiles;
</pre>
<p>avec ses getter / setter associés.</p>
<p>Grâce au mécanisme de l’ORM, l’appel au getter getProfiles() d’une instance de la classe user récupérée via le gestionnaire d’entité provoquera une requête SQL de type :</p>
<pre class="brush: sql">

SELECT p.*

FROM PROFILE_TABLE p, USER_PROFILES up

WHERE up.PROFILE_CODE = p.PROFILE_CODE AND up.USER_ID = ?
</pre>
<p>le résultat de cette requête permettant de créer la liste d’objets Profile dont je vous laisse imaginer le code.</p>
<h2>Les frameworks ORM</h2>
<p>Le framework Java le plus connu sur ce sujet est Hibernate, qui a notamment introduit ce concept (ou l’a du moins fait connaître), repris ensuite officiellement par la communauté Java sous le doux nom de <a href="http://www.oracle.com/technetwork/articles/javaee/jpa-137156.html" target="_blank">JPA</a> (Java Persistence Annotations). JPA permet notamment de définir les méta-données par l’intermédiaire d’annotations Java de type <strong>@Column</strong>, <strong>@Table</strong>, etc. &#8230;</p>
<p>.NET a vu un portage d’Hibernate appelé <a href="http://community.jboss.org/wiki/NHibernateforNET" target="_blank">NHibernate</a>, lancé dans le cadre de la «dotnetification» des frameworks Java (<a href="http://logging.apache.org/log4j/" target="_blank">log4j</a> devient <a href="http://logging.apache.org/log4net/" target="_blank">log4net</a>, <a href="http://www.junit.org/" target="_blank">JUnit</a> devient <a href="http://www.nunit.org/" target="_blank">NUnit</a>&#8230;). Pourtant la solution de <a href="http://msdn.microsoft.com/en-us/library/8s3saad7(v=vs.71).aspx" target="_blank">DataSet .NET</a> offrait déjà des fonctionnalités assez proches, et particulièrement bien intégrées à l’environnement de développement, mais j’imagine que cette opération a eu le mérite de permettre aux habitués du framework à transiter vers .NET de manière plus rapide et fluide. A noter, vu qu’on parle de .NET que depuis la version 3, on a vu apparaître le framework LINQ, avec notamment <a href="http://msdn.microsoft.com/en-us/library/bb425822.aspx" target="_blank">LINQ to SQL</a> qui se place en concurrent officiel de NHibernate, avec un périmètre bien plus large, notamment sur sa capacité à travailler sur les collections en mémoire à l&#8217;aide de prédicats proches du SQL. Pour le coup, et malgré un plugin <a href="http://www.hibernate.org/subprojects/tools.html" target="_blank">Hibernate Tools</a> proposé par JBoss sur Java, la solution Microsoft se montre particulièrement bien pensée au niveau de son intégration à l’environnement de développement (ce qu’on comprend parfaitement quand on regarde le prix de Visual Studio en face d’un eclipse gracieusement mis à disposition).</p>
<p>Je passe les portages divers et variés ayant pu voir le jour sur d’autres plateformes, n’ayant pas le recul nécessaire, mais je suis certains qu’il en existe.</p>
<h2>Le constat</h2>
<p>Après avoir pris le temps de comprendre le fonctionnement d’un ORM en l’utilisant sur des projets existants ou en tentant de le mettre en place sur des projets partant d’un développement «from scratch», je me suis heurté aux problèmes liés à la persistance et à ce fameux cache de premier niveau. En effet, travailler avec deux versions d’un même objet, l’un existant dans le cache et l’autre non (créé par exemple à l’issue d’une soumission de formulaire, peut facilement poser des problèmes de cohérence, et demandent qu’on tienne compte des particularités du concept d’ORM pour que les exceptions StaleObjectException ou LazyInitializationException soient gérées correctement (ou peut-être devrais-je dire «tant bien que mal»).</p>
<p>Et c’est là que le bât blesse : l’ORM, bien que simplifiant la gestion des accès à une base de données peut très facilement être une source de problèmes de performances ou de stabilité d’une application s’il n’est pas utilisé à bon escient, ou par une personne non encadrée d’un expert du domaine.</p>
<p>Imaginez que l’on cherche à parcourir la liste des rôles d’un utilisateur récupéré au moyen d’un ORM dans notre exemple de tout à l’heure :</p>
<pre class="brush: java">

Iterator&lt;Profile&gt; profilesIter = user.getProfiles().iterator();

while (profilesIter.hasNext())

{

Profile currentProfile = profilesIter.next();

Iterator&lt;Roles&gt; rolesIter = currentProfile.getRoles().iterator();

while (rolesIter.hasNext())

{

Role currentRole = rolesIter.next();

// Faire quelque chose

}

}
</pre>
<p>En pratique, il est tout à fait probable que ce code, presque indolore sur des collections d’objets présents en mémoire, se traduise avec un ORM par une série de requêtes SQL. En considérant que ce code serve à contrôler qu’un utilisateur dispose d’un rôle donné au sein d’une application – étant donc appelé très souvent pour chaque utilisateur de l’application – on peut tout à fait imaginer les problèmes de performances posés.</p>
<h2>« C’est un problème de paramétrage »</h2>
<p>Effectivement, ces problèmes sont souvent liés à la méconnaissance du framework et à des problèmes de paramétrage. Je ne suis moi-même pas expert Hibernate mais le connais assez pour savoir qu’un bon paramétrage peut faire toute la différence et que le code d’une application doit également se conformer au paradigme d’ORM.</p>
<p>J’ai aussi tendance à considérer ce type de travail comme un luxe. En effet, à niveau équivalent, un développeur sera capable de produire une requête SQL relativement efficace alors qu’il restera incapable de proposer un paramétrage Hibernate adéquat.</p>
<p>En conclusion, <strong>bien manipulé, l’ORM peut être très intéressant</strong> et apporter en lisibilité de code. A l’inverse, <strong>mal utilisé, il pose plus de problèmes qu’il n’est sensé en résoudre</strong> (performances, «hacks» divers et variés&#8230;).</p>
<h2>Les alternatives</h2>
<p>Et si je ne veux pas d’ORM sur mon projet ? C’est une question à se poser : les problèmes posés par un ORM, selon l’organisation et l’expérience de l’équipe de développement, peuvent être un frein à la réussite d’un projet.</p>
<p>Vous pouvez globalement recourir à :</p>
<ul>
<li>Un «mappeur de requêtes SQL» permettant d’exécuter des requêtes rédigées par vos soins, et automatiquement «mappées» sur des objets selon la configuration mise en place. Un framework Java assez connu dans ce domaine est <a title="iBatis" href="http://ibatis.apache.org/" target="_blank">iBatis</a> (repris récemment sous le nom <a title="MyBatis" href="http://www.mybatis.org/" target="_blank">MyBatis</a>) qui donne des résultats tout à fait satisfaisants, notamment par rapport à sa facilité de mise en oeuvre et sa proximité de fonctionnement avec des appels standards JDBC.</li>
<li>Des appels JDBC natifs «bruts» qui manquent de classes facilitant les appels et traitements des résultats. En le complétant du framework <a title="Documentation Spring 2 JDBC" href="http://static.springsource.org/spring/docs/2.0.x/reference/jdbc.html" target="_blank">Spring et son JdbcTemplate</a>, vous obtenez une solution très simple à mettre en place et aisément compréhensible par une équipe de développement peu expérimentée.</li>
</ul>
<h2>Que choisir ?</h2>
<p>Aujourd’hui, selon le contexte de la société dans laquelle un projet donné est réalisé, deux grandes catégories d’équipe se distinguent :</p>
<ol>
<li>Une équipe composée de profils similaires, évoluant ensemble sur les développements applicatifs de la société pour laquelle ils travaillent.</li>
<li>Une équipe encadrée par un senior et composée de profils juniors.</li>
</ol>
<p>Dans le premier cas de figure, la capitalisation sur la technologie sera généralement pérenne, l’équipe restant stable et organisée autour d’un socle applicatif donné. Dans ce cadre, les problèmes liés à l’utilisation d’un ORM ne se posent finalement qu’au démarrage et sont gommés par la suite.</p>
<p>Dans la seconde configuration, le cadrage est fait par l’architecte de manière globale, mais souvent difficilement appliqué à tous les aspects du développement. Concrètement, l’expert interviendra à la demande d’un junior coincé sur un problème, et règlera le problème avec lui en tentant de lui apporter les connaissances manquantes. Dans ce schéma, à force, les juniors intégreront les concepts et deviendront seniors à leur tour, encadrant d’autres juniors et l’histoire se répètera.</p>
<h2>Conclusions</h2>
<p>Vous aurez compris que je ne suis personnellement pas friand d’ORM, lui préférant des solutions plus simples, ayant trop souvent eu à gérer des problèmes liés à l’incompréhension du framework, des tentatives de paramétrage a posteriori pour contrer les problèmes de performances&#8230; Mais <strong>tout dépend de votre configuration d’équipe</strong>, cela reste un choix très intéressant dès lorsque qu’il est partagé et que chaque membre de l’équipe maîtrise les tenants et aboutissants de cette technologie.</p>
<p>Et vous, vous êtes ORM ?Autres articles sur le même sujet
<ul>
<li><a href="http://www.lafabrick.com/blog/2007/10/01/244-vous-avez-dis-flex3-beta2/" rel="bookmark" title="1 octobre 2007">Vous avez dis Flex3 Beta2 ?</a></li>
<li><a href="http://www.lafabrick.com/blog/2007/09/06/214-quicksilver-non-action-et-tao-appliqu-l-os-google-talks/" rel="bookmark" title="6 septembre 2007">Quicksilver, non-action et Tao appliqués à MacOS X [@Google Talks]</a></li>
<li><a href="http://www.lafabrick.com/blog/2009/10/09/1349-max-2009-jpa-blazeds-et-livecycle-ds/" rel="bookmark" title="9 octobre 2009">MAX 2009 &#8211; JPA, BlazeDS et LiveCycle DS</a></li>
<li><a href="http://www.lafabrick.com/blog/2010/08/20/2167-air-2-appeler-un-jar-executable-via-un-nativeprocess/" rel="bookmark" title="20 août 2010">AIR 2 : appeler un JAR exécutable via un NativeProcess</a></li>
</ul>
<p><!-- Similar Posts took 12.322 ms --></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lafabrick.com/blog/2011/02/26/2429-orm-hibernate-et-contrarietes/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>AIR 2 : appeler un JAR exécutable via un NativeProcess</title>
		<link>http://www.lafabrick.com/blog/2010/08/20/2167-air-2-appeler-un-jar-executable-via-un-nativeprocess/</link>
		<comments>http://www.lafabrick.com/blog/2010/08/20/2167-air-2-appeler-un-jar-executable-via-un-nativeprocess/#comments</comments>
		<pubDate>Fri, 20 Aug 2010 00:21:08 +0000</pubDate>
		<dc:creator>Hervé</dc:creator>
				<category><![CDATA[[Dev] Flash / Flex / AIR...]]></category>
		<category><![CDATA[AIR]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[JAR]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[linkedin]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[NativeProcess]]></category>

		<guid isPermaLink="false">http://www.lafabrick.com/blog/?p=2167</guid>
		<description><![CDATA[Vous avez certainement pu remarquer l&#8217;apparition attendue de la fonctionnalité d&#8217;exécution de code natif parmi les nouveautés de AIR 2.0. Les NativeProcess permettent d&#8217;étendre significativement les possibilités offertes par une application AIR. Mais, l&#8217;un des gros atouts d&#8217;Adobe AIR résidant dans sa nature multi-plateforme, il serait dommage de restreindre l&#8217;installation de votre application à un [...]]]></description>
			<content:encoded><![CDATA[<p>Vous avez certainement pu remarquer l&#8217;apparition attendue de la fonctionnalité d&#8217;exécution de code natif parmi les nouveautés de AIR 2.0. Les NativeProcess permettent d&#8217;étendre significativement les possibilités offertes par une application AIR.<br />
Mais, l&#8217;un des gros atouts d&#8217;Adobe AIR résidant dans sa nature multi-plateforme, il serait dommage de restreindre l&#8217;installation de votre application à un seul système d&#8217;exploitation&#8230; ça tombe bien, Java aussi est multi-plateforme (c&#8217;est bien l&#8217;open source) : OK du coup comment j&#8217;appelle du Java depuis mon AIR ?<br />
Explications&#8230;<br />
<span id="more-2167"></span></p>
<h2>Fonctionnement et limites d&#8217;un NativeProcess</h2>
<h3>Packaging de l&#8217;application</h3>
<p>Pour diverses raisons de sécurité, une application AIR utilisant un NativeProcess doit être packagée dans le format de la plateforme cible (exe pour Windows, dmg pour Mac, rpm / deb / &#8230; pour Linux). Fini donc dans ce cas le pratique fichier .air qui marche partout !<br />
Vous devez également indiquer dans le descripteur de l&#8217;application qu&#8217;il s&#8217;agit d&#8217;une application au profil &laquo;&nbsp;extendedDesktop&nbsp;&raquo; lui conférant donc les capacités d&#8217;exécuter un NativeProcess.<br />
Vous devez ouvrir le fichier <strong>monAppli-app.xml</strong> et modifier la balise <code>&lt;supportedProfiles&gt;</code></p>
<pre class="brush: xml">
&lt;supportedProfiles&gt;extendedDesktop&lt;/supportedProfiles&gt;
</pre>
<p>A partir de là, si vous tentez d&#8217;exporter un fichier .air, vous aurez un joli message d&#8217;erreur vous invitant à changer de profil.</p>
<h3>Considérations de sécurité</h3>
<p>Si AIR sans native process dispose de limitations de sécurité, dès lors que vous utilisez un native process, vous ouvrez la porte&#8230; Il est donc bon d&#8217;anticiper et de faire un maximum de vérifications sur vos appels pour éviter un remplacement d&#8217;un exécutable par un autre, moins sympathique, par exemple&#8230;</p>
<h2>Prêt ? On code</h2>
<h3>Paramétrage</h3>
<p>Un native process a besoin d&#8217;un contexte d&#8217;exécution. Ce contexte est défini à l&#8217;aide de l&#8217;objet <code>NativeProcessStartupInfo</code> décrivant notamment les éléments suivants :</p>
<ul>
<li><strong>workingDirectory</strong> : le répertoire d&#8217;exécution</li>
<li><strong>executableFile</strong> : l&#8217;exécutable à lancer</li>
<li><strong>arguments</strong> : la liste des arguments à passer à l&#8217;exécutable (<code>Vector.&lt;String&gt;</code> sous Flash Player 10, ou un bête <code>Array</code> sinon)</li>
</ul>
<p>Vous pourrez alors instancier un objet NativeProcess et lui passer cet objet de paramétrage avant de le lancer.</p>
<h3>Lancement &amp; suivi de l&#8217;exécution</h3>
<p>Le lancement d&#8217;un NativeProcess est asynchrone. Il propose donc un certain nombre d&#8217;événements vous permettant de suivre son exécution une fois lancé, notamment :</p>
<ul>
<li><strong>ProgressEvent.STANDARD_OUTPUT_DATA</strong> : écriture sur la sortie standard</li>
<li><strong>ProgressEvent.STANDARD_ERROR_DATA</strong> : écriture sur la sortie d&#8217;erreur</li>
<li><strong>IOErrorEvent.STANDARD_OUTPUT_IO_ERROR</strong> : déclenché lorsqu&#8217;une erreur apparaît en tentant de lire la sortie standard</li>
<li><strong>IOErrorEvent.STANDARD_ERROR_IO_ERROR</strong> : déclenché lorsqu&#8217;une erreur apparaît en tentant de lire la sortie d&#8217;erreur</li>
<li><strong>NativeProcessExitEvent.EXIT</strong> : déclenché lors que l&#8217;exécution du process est terminée</li>
</ul>
<h3>Lecture de l&#8217;entrée / sortie standard</h3>
<p>Bien que tout à fait possible, la lecture de la sortie standard ou d&#8217;erreur via le listener <code>ProgressEvent.STANDARD_OUTPUT_DATA</code> ou <code>ProgressEvent.STANDARD_ERROR_DATA</code> n&#8217;est pas fiable à 100% concernant le contenu retourné : la sortie étant &laquo;&nbsp;bufferisée&nbsp;&raquo;, vous n&#8217;aurez donc pas systématiquement le même résultat selon la machine exécutant le programme, à chaque appel de votre listener&#8230; N&#8217;utilisez donc la lecture de sortie standard que pour afficher ce qui se passe, ou à la limite récupérer la totalité du contenu écrit une fois le process terminé&#8230;</p>
<h2>Appeler un JAR</h2>
<h3>Rappels</h3>
<p>Pour appeler un JAR en Java, il doit être exécutable (bah oui&#8230;), et appelé en ligne de commande de la manière suivante :<br />
<code><br />
java -jar monJar.jar [-cp jars du classpath]<br />
</code><br />
Nous sommes dans une appli AIR, donc évitons de surcharger la commande à appeler avec un classpath, aussi je vous suggère d&#8217;utiliser les fonctionnalités d&#8217;export complets d&#8217;un JAR (si les licences associées vous l&#8217;autorisent) intégrant au final l&#8217;ensemble des sources dans un groooos JAR contenant tout ce qu&#8217;il lui faut pour fonctionner.<br />
<strong>Notes :</strong></p>
<ul>
<li>Les utilisateurs de Maven peuvent utiliser <a title="Plugin maven assembly et configuration associée" href="http://stackoverflow.com/questions/574594/how-can-i-create-an-executable-jar-with-dependencies-using-maven">le plugin qui va bien pour ça</a>.</li>
<li>L&#8217;export eclipse, c&#8217;est pas mal non plus, il suffit de cocher la &laquo;&nbsp;case qui va bien&nbsp;&raquo; au moment d&#8217;exporter</li>
</ul>
<h3>Depuis un NativeProcess</h3>
<p>On voit mieux ce qui se dessine:</p>
<ol>
<li>Définir l&#8217;exécutable java dans vos &laquo;&nbsp;startup infos&nbsp;&raquo;</li>
<li>Définir les arguments
<ul>
<li>-jar</li>
<li>/chemin/vers/monJar.jar</li>
</ul>
</li>
<li>Ajouter les listeners permettant de savoir lorsque l&#8217;exécution est terminée</li>
<li>Lancer le native process</li>
</ol>
<h3>Restons multi plateforme</h3>
<p>Java est multi plateforme, oui, mais l&#8217;exécutable dépend de la plateforme, aussi il vous faudra récupérer le chemin vers votre JAVA_HOME (contenant le répertoire bin avec l&#8217;exécutable Java).<br />
Vous avez donc deux solutions maintenant:</p>
<ol>
<li><strong>La plus simple</strong> (pour le développeur) : demander à votre gentil utilisateur où est son JAVA_HOME. Ça peut le faire si c&#8217;est un geek velu qui a compris qu&#8217;on ne parlait pas de venir danser chez lui (aïe, elle est rude celle-ci)</li>
<li><strong>La plus compliquée</strong> (mais pratique pour l&#8217;utilisateur) : utiliser un autre exécutable (voire NativeProcess) qui remonte cette information ou permette de pointer directement sur l&#8217;exécutable en question</li>
</ol>
<p>La seconde solution bien que séduisante est un peu plus longue à implémenter.<br />
Pour les développeurs sous Windows, j&#8217;ai noté l&#8217;utilisation par <a href="www.webkitchen.be">Serge Jespers</a> d&#8217;un petit (mais pratique) exécutable &laquo;&nbsp;jexe.exe&nbsp;&raquo; lançant le java.exe présent dans le %JAVA_HOME%\bin de la machine. L&#8217;utiliser vous évitera la première solution, sans vous lancer dans un développement spécifiquement dédié à cela (merci Serge). En revanche, si votre application est diffusée à un public d&#8217;utilisateurs non avertis, ils sont tout à fait susceptibles de ne pas avoir de variable JAVA_HOME définie sur leur machine : pensez donc à déterminer précisément votre cible avant de choisir une solution.</p>
<p>J&#8217;ai également noté en relisant un extrait de la licence du JRE que la redistribution est autorisée sous certaines conditions. Si vous les remplissez, vous pourriez carrément embarquer le runtime java dans votre application AIR, au risque de la faire gonfler en taille&#8230;</p>
<h2>Un exemple ! Un exemple !</h2>
<p>Voici un petit exemple de code permettant de lancer un JAR exécutable depuis une application AIR :</p>
<pre class="brush: java">
package com.lafabrick.nativeprocess
{
import flash.desktop.NativeProcess;
import flash.desktop.NativeProcessStartupInfo;
import flash.events.EventDispatcher;
import flash.events.NativeProcessExitEvent;
import flash.events.ProgressEvent;
import flash.filesystem.File;
import flash.system.Capabilities;

public class JarExec
{
protected var _process:NativeProcess;

public function JarExec()
{
}

public function getDefaultJavaExecutable():File
{
if (Capabilities.os.toLowerCase().indexOf(&quot;win&quot;) &gt; -1)
{
return File.applicationDirectory.resolvePath(&quot;native/jexe.exe&quot;);
}
if (Capabilities.os.toLowerCase().indexOf(&quot;mac&quot;) &gt; -1)
{
// TODO: Changer avec un paramètre de configuration
return new File(&quot;/System/Library/Frameworks/JavaVM.framework/Commands/java&quot;);
}
throw new Error(&quot;Système non pris en charge&quot;);
return null;
}

public function testJava(executablePath:String = null):void
{
// Tester le lancement de l&#039;exécutable &#039;java&#039;
try
{
var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
nativeProcessStartupInfo.workingDirectory = File.applicationDirectory;
nativeProcessStartupInfo.executable = (executablePath == null ? getDefaultJavaExecutable() : new File(executablePath));

var args:Vector.&lt;String&gt; = new Vector.&lt;String&gt;();
args.push(&quot;-version&quot;);
nativeProcessStartupInfo.arguments = args;

_process = new NativeProcess();
_process.addEventListener(NativeProcessExitEvent.EXIT, onJavaTestExit);
_process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onStandardOut);
_process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, onErrorOut);
_process.start(nativeProcessStartupInfo);

trace(&quot;-- Début d&#039;exécution&quot;);
}
catch (e:Error)
{
trace(&quot;Impossible de lancer le process\n&quot; + e.message + &quot;\n&quot; + e.getStackTrace());
}
}
protected function onStandardOut(e:ProgressEvent):void
{
trace(&quot;STDOUT: &quot; + _process.standardOutput.readUTFBytes(_process.standardOutput.bytesAvailable));
}
protected function onErrorOut(e:ProgressEvent):void
{
trace(&quot;STDERR: &quot; + _process.standardError.readUTFBytes(_process.standardError.bytesAvailable));
}
protected function onJavaTestExit(e:NativeProcessExitEvent):void
{
trace(&quot;-- Fin d&#039;exécution&quot;);
}
}
}
</pre>
<p>Cet extrait donne un aperçu, mais vous pouvez vous lancer (soyons fous) à installer le package suivant :</p>
<table style="text-align: center;">
<tbody>
<tr>
<td><a href="http://www.lafabrick.com/labz/nativeprocess/NativeJarExec.dmg"><img title="Mac" src="http://www.lafabrick.com/blog/wp-content/uploads/2010/07/mac.gif" alt="" width="50" height="50" /><br />
Pour Mac</a></td>
<td><a href="http://www.lafabrick.com/labz/nativeprocess/NativeJarExec.exe"><img title="Windows" src="http://www.lafabrick.com/blog/wp-content/uploads/2010/07/windows.jpeg" alt="" width="50" height="50" /><br />
Pour Windows</a></td>
</tr>
</tbody>
</table>
<p>Pensez au clic droit &gt; View Source&#8230;</p>
<h2>Packager l&#8217;application</h2>
<p>Comme je le disais au début de ce post, il est nécessaire de packager votre application dans le format natif du système d&#8217;exploitation visé. Vous avez deux solutions pour cela :</p>
<ol>
<li>Passer par la dernière version de Flash Builder 4 qui propose cette fonctionnalité</li>
<li>Utiliser l&#8217;application <a href="http://www.webkitchen.be/package-assistant-pro/">PackageAssistantPro</a> proposée par <a href="http://www.webkitchen.be">Serge Jespers</a> (re merci Serge)</li>
</ol>
<p>Il s&#8217;agit d&#8217;une application AIR utilisant des NativeProcess (et packagée en ligne de commande vu que l&#8217;application n&#8217;existait pas avant&#8230; Remarquez, la version 2 et plus ont probablement été packagées avec la version 1&#8230; Mais je m&#8217;égare)</p>
<h2>Quelques liens</h2>
<ul>
<li>Un petit exemple d&#8217;application utilisant un NativeProcess : <a href="http://www.lafabrick.com/blog/2010/07/28/2092-zxpackager-application-pour-l%e2%80%99empaquetage-zxp-d%e2%80%99extensions-cs5/">ZXPackager</a></li>
<li><a lang="en_US" href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/desktop/NativeProcess.html">ASDoc de la classe NativeProcess [EN]</a></li>
<li><a lang="en_US" href="http://www.adobe.com/devnet/air/flex/quickstart/interacting_with_native_process.html">Un bon article pour démarrer [EN]</a></li>
</ul>
<p>Autres articles sur le même sujet
<ul>
<li><a href="http://www.lafabrick.com/blog/2008/02/04/299-un-projet-java-flex-avec-maven-2/" rel="bookmark" title="4 février 2008">Un projet Java / Flex avec Maven 2</a></li>
<li><a href="http://www.lafabrick.com/blog/2010/04/06/1754-arduino-2-flash-socket-et-processing/" rel="bookmark" title="6 avril 2010">Arduino #2 : Flash, socket et Processing</a></li>
<li><a href="http://www.lafabrick.com/blog/2010/07/28/2092-zxpackager-application-pour-l%e2%80%99empaquetage-zxp-d%e2%80%99extensions-cs5/" rel="bookmark" title="28 juillet 2010">ZXPackager : application pour l’empaquetage ZXP d’extensions CS5</a></li>
<li><a href="http://www.lafabrick.com/blog/2010/10/21/2272-rollingfiletarget-pour-air-2-0-lets-roll/" rel="bookmark" title="21 octobre 2010">RollingFileTarget pour AIR 2.0 : let&#8217;s roll !</a></li>
</ul>
<p><!-- Similar Posts took 12.325 ms --></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lafabrick.com/blog/2010/08/20/2167-air-2-appeler-un-jar-executable-via-un-nativeprocess/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>MAX 2009 &#8211; JPA, BlazeDS et LiveCycle DS</title>
		<link>http://www.lafabrick.com/blog/2009/10/09/1349-max-2009-jpa-blazeds-et-livecycle-ds/</link>
		<comments>http://www.lafabrick.com/blog/2009/10/09/1349-max-2009-jpa-blazeds-et-livecycle-ds/#comments</comments>
		<pubDate>Fri, 09 Oct 2009 09:00:23 +0000</pubDate>
		<dc:creator>Hervé</dc:creator>
				<category><![CDATA[[Dev] Flash / Flex / AIR...]]></category>
		<category><![CDATA[BlazeDS]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[LiveCycle]]></category>

		<guid isPermaLink="false">http://www.lafabrick.com/blog/?p=1349</guid>
		<description><![CDATA[Aoutch ! Rien que le titre fait un peu peur. L&#8217;idée de cette conférence est de présenter le framework JPA (Java Persistence API) et son utilisation dans le cadre d&#8217;un projet Flex avec BlazeDS ou LiveCycle Data Services. Oui, c&#8217;est velu, mais ça passe. A savoir que je n&#8217;ai pas assisté à la totalité de [...]]]></description>
			<content:encoded><![CDATA[<div class="mceTemp mceIEcenter">
<div>
<div class="mceTemp mceIEcenter">
<dl id="attachment_1368" class="wp-caption aligncenter" style="width: 530px;">
<dt class="wp-caption-dt"><img class="size-full wp-image-1368" title="jpa" src="http://www.lafabrick.com/blog/wp-content/uploads/2009/10/jpa.jpg" alt="ca pique!" width="520" height="130" /> </dt>
</dl>
</div>
</div>
</div>
<p>Aoutch ! Rien que le titre fait un peu peur. L&#8217;idée de cette conférence est de présenter le framework JPA (Java Persistence API) et son utilisation dans le cadre d&#8217;un projet Flex avec BlazeDS ou LiveCycle Data Services.</p>
<p>Oui, c&#8217;est velu, mais ça passe.</p>
<p>A savoir que je n&#8217;ai pas assisté à la totalité de la conférence, pour pouvoir rencontrer plus de personnes sur les stands.</p>
<p>Que les non techniciens s&#8217;arrêtent ici, et ne cliquent pas sur &laquo;&nbsp;Lire la suite&nbsp;&raquo; sous peine de maux de tête.<br />
<span id="more-1349"></span></p>
<h2>JPA / Hibernate</h2>
<h3>JPA</h3>
<p>Il s&#8217;agit d&#8217;un framework permettant de concevoir sa base de données à partir de POJOs Java, auxquels sont ajoutés des annotations JPA. Ces annotations permettent de définir un modèle de données sous-jacent, qui pourra par la suite être créé physiquement sur la base de données de votre choix à l&#8217;aide d&#8217;une tâche Ant.</p>
<p>J&#8217;ai bien aimé leur anecdote : ils sont trois développeurs, et utilisent tous les trois des IDE différents et des bases de données différentes, mais comme ils ont JPA et que ce dernier permet de regénérer la base de données via Ant et ce quelque soit le SGBD cible, ils s&#8217;en foutent (oui, ils sont fous ces types).</p>
<p>Si vous n&#8217;avez rien compris, allez sur <a href="http://www.lequipe.fr">lequipe.fr</a>, ça sera sûrement plus productif.</p>
<h3>Hibernate</h3>
<p><img class="size-thumbnail wp-image-188 " style="float: right; border: none;" title="The path through JPA" src="http://herve.lafabrick.com/blog/wp-content/uploads/2009/10/IMG_2920-150x150.jpg" alt="The path through JPA" width="150" height="150" /></p>
<p>Il faut savoir ensuite que JPA reste une API, et qui dit API dit interface, aussi est-il nécessaire d&#8217;y adjoindre une implémentation. C&#8217;est ici qu&#8217;hibernate intervient. Concrètement, en définissant votre modèle de données avec JPA, vous pourrez utiliser Hibernate comme exécutant et vous permette d&#8217;interroger votre base de données. Le gros intérêt ici, c&#8217;est que JPA vous offre la possibilité de vous affranchir d&#8217;une configuration supplémentaire à l&#8217;aide des fameux fichiers HBM au format XML, les annotations JPA décrivant déjà cette information.</p>
<p>Pour le reste, les classes de votre couche prenant en charge l&#8217;accès aux données utiliseront Hibernate comme avant (je suis sûr que vous utilisiez déjà Hibernate avant, mais si).</p>
<p>J&#8217;avais prévenu, JPA, ça pique surtout quand il arrive avec son pote Hibernate.</p>
<h2 style="clear: both">Spring et BlazeDS</h2>
<p>Comme on s&#8217;ennuyait un peu et qu&#8217;il n&#8217;y avait pas assez de frameworks, on embraye sur l&#8217;utilisation de Spring et BlazeDS.</p>
<p>Les conférenciers nous présentent comment utiliser Spring pour configurer les canaux de discussion entre Flex et les services Java (i.e. le message broker). Pour le coup, je connaissais déjà, mais un petit rappel sur le sujet est bon à donner compte tenu de la simplification apportée dans la configuration (si tant est qu&#8217;on utilise Spring) à l&#8217;aide de <a href="http://www.springsource.org/spring-flex">spring-flex</a>.</p>
<p>Concrètement il suffit de déclarer dans la configuration XML Spring des beans avec le namespace <code>flex:</code> pour déclarer les destinations que vous pourrez ensuite utiliser avec un <code>RemoteObject</code> Flex.</p>
<p>On peut donc mapper des services Java via Spring comme ça :</p>
<p><img class="alignnone size-full wp-image-192" title="Configuration Spring BlazeDS" src="http://herve.lafabrick.com/blog/wp-content/uploads/2009/10/config-spring.png" alt="Configuration Spring BlazeDS" width="587" height="220" /></p>
<p>C&#8217;est bien pratique quand on sait ce qu&#8217;il fallait faire avant pour dire à BlazeDS d&#8217;utiliser un bean Spring comme service.</p>
<h2>LiveCycle DS</h2>
<p><img class="size-full wp-image-169" style="float: left; border: none;" title="Adobe LiveCycle Enterprise Suite" src="http://herve.lafabrick.com/blog/wp-content/uploads/2009/10/adobe-lifecycle-logo.jpg" alt="Adobe LiveCycle Enterprise Suite" width="90" height="90" />La conférence commençant à tourner court, et le sujet étant principalement les avantages de LiveCycle Data Services par rapport à BlazeDS, j&#8217;ai quitté la salle. J&#8217;avoue également que le dynamisme n&#8217;était pas particulièrement au rendez-vous (on ne peut pas être un super velu et un gai luron en même temps il faut croire, parce qu&#8217;ils étaient vraiment, vraiment super velus).</p>
<p>Je vous laisserai donc consulter le web pour connaître ces différences, qui seront certainement mieux couvertes par un article consacré, mais ce que j&#8217;ai retenu avant de partir : possibilité d&#8217;utiliser RTMP, lazy loading.</p>
<h2>Conclusion</h2>
<p>J&#8217;ai eu un aperçu assez clair de JPA et de son intérêt : développer son modèle de données sous forme de classes Java et ne pas se soucier plus que ça de la base de données si ce n&#8217;est lors de la définition des annotations. Intéressant : pour une fois qu&#8217;un framework comme cela ne nécessite pas plus de configuration que cela et permet même d&#8217;en supprimer, c&#8217;est bien !</p>
<p>Enfin, peu voire pas de techno Flex dans cette conférence&#8230; Peut-être était-ce le lot de consolation pour les purs développeurs Java assistant à MAX ? Dommage.Autres articles sur le même sujet
<ul>
<li><a href="http://www.lafabrick.com/blog/2008/02/04/299-un-projet-java-flex-avec-maven-2/" rel="bookmark" title="4 février 2008">Un projet Java / Flex avec Maven 2</a></li>
<li><a href="http://www.lafabrick.com/blog/2009/01/15/819-reflex-2-vous-reprendez-bien-un-peu-de-ioc/" rel="bookmark" title="15 janvier 2009">Reflex #2 : vous reprendrez bien un peu de IOC ?</a></li>
<li><a href="http://www.lafabrick.com/blog/2010/08/20/2167-air-2-appeler-un-jar-executable-via-un-nativeprocess/" rel="bookmark" title="20 août 2010">AIR 2 : appeler un JAR exécutable via un NativeProcess</a></li>
<li><a href="http://www.lafabrick.com/blog/2011/02/26/2429-orm-hibernate-et-contrarietes/" rel="bookmark" title="26 février 2011">ORM, Hibernate et contrariétés&#8230;</a></li>
</ul>
<p><!-- Similar Posts took 11.842 ms --></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lafabrick.com/blog/2009/10/09/1349-max-2009-jpa-blazeds-et-livecycle-ds/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Un projet Java / Flex avec Maven 2</title>
		<link>http://www.lafabrick.com/blog/2008/02/04/299-un-projet-java-flex-avec-maven-2/</link>
		<comments>http://www.lafabrick.com/blog/2008/02/04/299-un-projet-java-flex-avec-maven-2/#comments</comments>
		<pubDate>Mon, 04 Feb 2008 18:31:14 +0000</pubDate>
		<dc:creator>Hervé</dc:creator>
				<category><![CDATA[La Fabrick]]></category>
		<category><![CDATA[[Dev] Flash / Flex / AIR...]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[Tutoriels]]></category>

		<guid isPermaLink="false">http://92.243.2.196/lafabrick/blog/?p=299</guid>
		<description><![CDATA[<p>Après un premier tuto sur la création d'un projet Flex avec Maven 2, nous pouvons maintenant nous pencher sur un chantier plus important encore&#160;: comment compiler mon Flex <strong>puis</strong> ma webapp Java en une fois avec Maven 2&#160;?</p> <p>Comment personnaliser un peu la compilation Flex pour l'adapter à mes besoins ?</p> <p>C'est par là...</p>]]></description>
			<content:encoded><![CDATA[<p>Après un premier tuto sur la création d&#8217;un projet Flex avec Maven 2, nous pouvons maintenant nous pencher sur un chantier plus important encore : comment compiler mon Flex <strong>puis</strong> ma webapp Java en une fois avec Maven 2 ?</p>
<p>Comment personnaliser un peu la compilation Flex pour l&#8217;adapter à mes besoins ?</p>
<p>C&#8217;est par là&#8230;</p>
<p><span id="more-299"></span></p>
<h2>Introduction</h2>
<p>Si vous êtes ici, c&#8217;est donc que vous disposez :</p>
<ul>
<li>d&#8217;un fichier <em>start.cmd</em> qui vous permet de lancer une ligne de commande permettant l&#8217;usage de Maven avec Flex</li>
<li>d&#8217;un projet Flex de test, constructible via Maven 2 et donc de son fichier <em>pom.xml</em></li>
</ul>
<h3>Ce que nous allons faire</h3>
<p>L&#8217;objectif est simple, une application Flex ne venant jamais seule, il devient rapidement intéressant de non seulement construire son SWF, mais également de préparer son WAR. Dans ces cas là, il devient intéressant de pouvoir effectuer ces tâches en une seule fois.</p>
<h3>En pratique</h3>
<p>Maven offre une possibilité très intéressante : le POM parent. Il s&#8217;agit en fait d&#8217;un &laquo;&nbsp;Meta POM&nbsp;&raquo; décrivant un ensemble de modules d&#8217;un projet plus global. Vous l&#8217;avez compris, votre projet global est une application Java / Flex, vos modules sont :</p>
<ul>
<li>L&#8217;application Flex d&#8217;un côté</li>
<li>La webapp Java de l&#8217;autre</li>
</ul>
<p>De ce fait, nous allons avoir trois fichiers pom.xml :</p>
<ol>
<li>Le POM parent décrivant le projet global (le fameux Meta POM)</li>
<li>Le POM du projet Flex</li>
<li>Le POM du projet Java</li>
</ol>
<h2>A nos outils</h2>
<h3>Construction de l&#8217;arborescence du projet</h3>
<p>Maven propose (encore ?!) un outil très intéressant : les archetype. L&#8217;idée est de permettre la construction d&#8217;une arborescence type de projet en une ligne de commande.</p>
<p>Si je reprends l&#8217;arborescence du toto précédent, vous devez vous positionner dans le répertoire parent de <em>demo-flex</em>, soit, dans l&#8217;exemple suivant, au niveau de <em>lafabrick</em> :</p>
<p><img src="/blog/images/maven 2/arboProjet2.jpg" alt="" /></p>
<p>Vous pouvez alors exécuter la fameuse ligne de commande : <code>mvn archetype:create -DgroupId=com.lafabrick -Dpackagename=com.lafabrick -DartifactId=demo-java -DarchetypeArtifactId=maven-archetype-webapp</code></p>
<p>A la suite de cela, vous pouvez constater que l&#8217;arborescence suivante a été créée :</p>
<p><img src="/blog/images/maven 2/arboProjet3.jpg" alt="" /></p>
<p>Vous constaterez également qu&#8217;un fichier <em>pom.xml</em> a été automatiquement créé dans le répertoire <em>demo-java</em>. Ce fichier est un fichier standard décrivant une webapp Java. Il ne reste à présent plus qu&#8217;à créer notre Meta POM et a indiquer à nos deux modules qu&#8217;ils sont des modules de ce dernier.</p>
<p>Voici le fichier <em>pom.xml</em> à créer au niveau du répertoire <em>lafabrick</em> (cf. arborescence ci-dessus).</p>
<pre class="brush: xml">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;
xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&quot;&gt;

&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
&lt;groupId&gt;com.lafabrick&lt;/groupId&gt;
&lt;artifactId&gt;parent&lt;/artifactId&gt;
&lt;packaging&gt;pom&lt;/packaging&gt;
&lt;version&gt;1.0&lt;/version&gt;
&lt;name&gt;Projet Java Flex avec lafabrick&lt;/name&gt;
&lt;url&gt;http://maven.apache.org&lt;/url&gt;
&lt;dependencies&gt;
&lt;dependency&gt;
&lt;groupId&gt;junit&lt;/groupId&gt;
&lt;artifactId&gt;junit&lt;/artifactId&gt;
&lt;version&gt;3.8.1&lt;/version&gt;
&lt;scope&gt;test&lt;/scope&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;modules&gt;
&lt;module&gt;demo-flex&lt;/module&gt;
&lt;module&gt;demo-java&lt;/module&gt;
&lt;/modules&gt;
&lt;/project&gt;
</pre>
<p>Ce Meta POM (oui, j&#8217;aime bien cette expression bizarre) est finalement plutôt synthétique : il indique bien nos deux modules <em>demo-java</em> et <em>demo-flex</em> comme faisant partie d&#8217;un projet global nommé <em>Projet Java Flex avec lafabrick</em>.</p>
<p>Il reste à présent encore une dernière chose à faire : lier nos module au Meta POM (yes !).</p>
<p>Pour cela, ouvrez les fichiers <em>pom.xml</em> de chacun des projets et ajoutez-y les informations suivantes en tête de fichier (juste après le noeud racine <code>&lt;project&gt;</code>)</p>
<pre class="brush: js">
&lt;parent&gt;
&lt;groupId&gt;com.lafabrick&lt;/groupId&gt;
&lt;artifactId&gt;parent&lt;/artifactId&gt;
&lt;version&gt;1.0&lt;/version&gt;
&lt;/parent&gt;
</pre>
<p>Testons l&#8217;ensemble :</p>
<ul>
<li>rendez-vous dans le répertoire <em>lafabrick</em></li>
<li>ouvrez votre ligne de commande et tapez <code>mvn clean package</code></li>
</ul>
<p>Le résultat : nous avons à présent un fichier <strong>demo-flex-1.0.swf</strong> dans <em>demo-flex/target</em> et (entre autres) un fichier <strong>demo-java.war</strong> dans le répertoire <em>demo-java/target</em>.</p>
<p>Mouais, pas mal, mais comment faire en sorte que le résultat de ma compil SWF aille dans ma webapp ? C&#8217;est simple, il suffit de modifier la propriété <code>directory</code> de votre projet flex.</p>
<p>Pour cela, modifiez le fichier <em>pom.xml</em> du projet Flex en ajoutant, dans la balise <code>&lt;build&gt;</code>, la ligne suivante :</p>
<pre class="brush: js">
&lt;directory&gt;${basedir}/../demo-java/src/main/webapp/flex&lt;/directory&gt;
</pre>
<p>Enregistrez et relancez la commande de construction du projet (comme tout à l&#8217;heure).</p>
<p>Voilà qui est mieux ! Le résultat est placé dans le répertoire <em>demo-java/src/main/webapp/flex</em> qui est ensuite inclus dans le WAR.</p>
<p><strong>Attention cependant : en manipulant le répertoire de sortie du SWF, maven va, à chaque <em>clean</em>, supprimer la totalité du répertoire concerné, aussi, n&#8217;indiquez pas <em>demo-java/src/main/webapp</em>, vous vou retrouveriez à supprimer l&#8217;ensemble des sources de la webapp !</strong>;</p>
<h2>Aller plus loin</h2>
<h3>BlazeDS ?</h3>
<p>Vous pourriez en vouloir un peu plus, notamment concernant les options de compilation de l&#8217;application Flex : il est probable que vous ayez à indiquer par exemple le fichier &lt;em&gt;services-config.xml&lt;/em&gt; à utiliser dans le cadre de l&#8217;utilisation des <a hreflang="en" href="labs.adobe.com/technologies/blazeds">BlazeDS</a>. Il faut savoir que le plugin ServeBox permet de modifier toutes (ou presque) les options de compilations disponibles avec <code>mxmlc</code>.</p>
<p>Aussi, je peux modifier mon fichier <em>pom.xml</em> le fichier <em>services-config.xml</em> à utiliser :</p>
<pre class="brush: js">
&amp;lt;build&amp;gt;
&lt;directory&gt;${basedir}/../demo-java/src/main/webapp/flex&lt;/directory&gt;
&amp;lt;plugins&amp;gt;
&amp;lt;plugin&amp;gt;
&amp;lt;groupId&amp;gt;org.servebox.flex2&amp;lt;/groupId&amp;gt;
&amp;lt;artifactId&amp;gt;flex2-plugin&amp;lt;/artifactId&amp;gt;
&amp;lt;version&amp;gt;0.9.1&amp;lt;/version&amp;gt;
&amp;lt;extensions&amp;gt;true&amp;lt;/extensions&amp;gt;
&amp;lt;configuration&amp;gt;
&amp;lt;sourceDirectory&amp;gt;/src/main/flex&amp;lt;/sourceDirectory&amp;gt;
&amp;lt;mxmlFile&amp;gt;src/main/flex/Main.mxml&amp;lt;/mxmlFile&amp;gt;
&amp;lt;services&amp;gt;${basedir}/../demo-java/src/main/webapp/WEB-INF/flex/services-config.xml&amp;lt;/services&amp;gt;
&amp;lt;contextroot&amp;gt;demo-java&amp;lt;/contextroot&amp;gt;
&amp;lt;/configuration&amp;gt;
&amp;lt;/plugin&amp;gt;
&amp;lt;/plugins&amp;gt;
&amp;lt;/build&amp;gt;
</pre>
<p>Et voilà qui est fait.</p>
<h3>Les différentes options disponibles pour l&#8217;instant&#8230;</h3>
<p>Après un tour dans les sources du plugin, on retrouve la liste suivante des possibilités de paramétrage :</p>
<ul>
<li><strong>home</strong> (chemin vers le répertoire du SDK)<br />
Par défaut, prendra la valeur de la variable d&#8217;environnement <em>FLEX_HOME</em></li>
<li><strong>config</strong> (chemin vers le fichier <em>flex-config.xml</em> du SDK)<br />
Par défaut : <em>${flex2.sdk.home}/frameworks/flex-config.xml</em></li>
<li><strong>out</strong> (répertoire cible de la génération du SWF / SWC)<br />
Par défaut : le répertoire <code>&lt;directory&gt;</code> indiqué dans la section <code>&lt;build&gt;</code> du POM</li>
<li><strong>source</strong> (répertoire de sources Flex)<br />
Par défaut : <em>src/main/flex</em></li>
<li><strong>optimize</strong> (optimisation du bytecode)<br />
Par défaut : <em>true</em></li>
<li><strong>strict</strong> (mode strict)<br />
Par défaut : <em>true</em></li>
<li><strong>Xmx</strong> (taille de la mémoire en Mo allouée au compilateur)<br />
Par défaut : <em>128</em></li>
<li><strong>contextroot</strong> (nom du contexte de la webapp)<br />
Par défaut : <em>- vide -</em></li>
<li><strong>services</strong> (fichier <em>services-config.xml</em> à utiliser)<br />
Par défaut : <em>- vide -</em></li>
<li><strong>useNetwork</strong> (utilisation du réseau ou non)<br />
Par défaut : <em>true</em></li>
<li><strong>chartinglicence</strong> (votre licence des composants graphiques)<br />
Par défaut : <em>- vide -</em></li>
<li><strong>asencoding</strong> (encodage de caractères des sources AS)<br />
Par défaut : <em>utf-8</em></li>
<li><strong>debug</strong> (mode debug)<br />
Par défaut : <em>false</em></li>
<li><strong>showbindingwarnings</strong> (warning sur les détections de changements de contrôle non pris en compte)<br />
Par défaut : <em>true</em></li>
<li><strong>showaswarnings</strong> (warning sur les classes ActionScript)<br />
Par défaut : <em>true</em></li>
<li><strong>showdeprecationwarnings</strong> (warning si utilisation de notations dépréciées)<br />
Par défaut : <em>true</em></li>
<li><strong>showtypeselectorwarnings</strong> (warning si utilisation <code>&lt;mx:Style&gt;</code>)<br />
Par défaut : <em>true</em></li>
<li><strong>accessible</strong> (mode accessible)<br />
Par défaut : <em>false</em></li>
</ul>
<p>Avec ça, si on peut pas faire du Flex avec Maven, c&#8217;est que vous utilisez les modules (RSL), et que ce n&#8217;est pas encore pris en compte&#8230;</p>
<p>A bientôt !Autres articles sur le même sujet
<ul>
<li><a href="http://www.lafabrick.com/blog/2007/07/25/194-installer-son-environnement-de-dveloppement-tomcat-eclipse-wtp-flex-builder-maven-2/" rel="bookmark" title="25 juillet 2007">Installer son environnement de développement : Tomcat &#8211; Eclipse &#8211; WTP &#8211; Flex Builder</a></li>
<li><a href="http://www.lafabrick.com/blog/2007/10/14/254-maven-2-flex-2-une-synergie-possible/" rel="bookmark" title="14 octobre 2007">Maven 2 &#8211; Flex 2 &#8211; une synergie possible ?</a></li>
<li><a href="http://www.lafabrick.com/blog/2007/10/03/256-titre/" rel="bookmark" title="3 octobre 2007">Utiliser Cairngorm dans un projet Flex / AMFPHP</a></li>
<li><a href="http://www.lafabrick.com/blog/2010/08/20/2167-air-2-appeler-un-jar-executable-via-un-nativeprocess/" rel="bookmark" title="20 août 2010">AIR 2 : appeler un JAR exécutable via un NativeProcess</a></li>
</ul>
<p><!-- Similar Posts took 14.857 ms --></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lafabrick.com/blog/2008/02/04/299-un-projet-java-flex-avec-maven-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

