Exporter des plugins Eclipse en ligne de commande

Pour faire suite à mon article sur le déploiement de produit headless, voici un exemple illustrant comment il est également possible de n'exporter que des plugins, afin de pouvoir les mettre à jour par simple copie dans la distribution finale sans avoir à exporter tout le produit.

Export classique via IHM

L'IDE fournit nativement la possibilité d'exporter (via Ant) un ou des plugins. L'option intéressante de cet outil est la sauvegarde du script Ant appelé, qui sera utilisé plus loin en ligne de commande.

Ainsi, dans le menu File > Export se trouve l'action "Deployable plug-ins and fragments" :

Dans le panneau suivant, voici l'option à utiliser :

Le script produit ressemble à :

<project default="plugin_export" name="build">
 <target name="plugin_export">
  <pde.exportPlugins destination="C:\test" exportSource="false" 
   exportType="directory" 
   plugins="com.developpef.plugin1,com.developpef.plugin2" 
   qualifier="v20120627" useJARFormat="true"/>
 </target>
</project>

Export via ligne de commande

Pour utiliser ce script Ant en ligne de commande, voici la procédure à utiliser :

start /wait eclipse.exe -noSplash -application org.eclipse.ant.core.antRunner 
 -data ..\..\workspace -buildfile buildPatch.xml

  • l'instruction "wait" permet à la console d'attendre la fin de l'exécution
  • "eclipse.exe -noSplash" permet de lancer une instance du moteur d'Eclipse sans splashScreen
  • le paramètre "application" indique au moteur de l'IDE de n'exécuter que le antRunner et non pas l'ouverture de l'interface
  • le paramètre "data" indique le chemin vers le workspace
  • le paramètre "buildfile " indique le chemin vers le fichier Ant à exécuter

Il est tout de même nécessaire de lancer Eclipse car le script Ant contient une tâche "pde.exportPlugins" qui requiert la mise en place de variables et autres scripts internes à l'IDE.

Avec ces simples éléments, il est alors possible de produire à la volée les plugins à partir d'un environnement de développement, en mode "silencieux" (sans interface).

Sources :


Fichier(s) joint(s) :



Les bons outils pour démarrer avec Android

Comme je l'ai évoqué dans mon précédent article sur le sujet, j'ai dernièrement "essuyé les plâtres du débutant" quant à la mise en place d'un environnement de développement "optimal" pour Android.

Après avoir fait de nombreuses et vaines recherches pour essayer de trouver un retour d'expérience sur le sujet, j'ai décidé de publier le mien. Cet article étant tout à fait subjectif, je vous invite donc à critiquer, commenter, suggérer des idées sur votre expérience!

Le bon IDE

Etant un fervent adepte d'Eclipse, j'ai cependant vite été déçu par les lenteurs et pertes de performances dues aux plugins Android. Je me suis donc orienté vers IntelliJ qui supporte nativement les outils nécessaires et présente donc une fluidité d'utilisation bien meilleure.

Optimiser le déploiement

Pour tester l'application sur le terminal, il est indispensable de régulièrement re-construire le fichier APK pour le publier à nouveau. L'IDE propose cette fonctionnalité mais relance à chaque déploiement la compilation intégrale des sources, la génération des ressources (classe R.java ...) et passe généralement par l'étape de signature du fichier (ce qui implique la saisie du mot de passe etc). Pour contourner cette gêne, il est préférable de déployer à partir de ANT. En effet, les sources contiennent par défaut le fichier build.xml nécessaire. Il suffit donc d'utiliser la ligne de commande :

ant -Dsdk.dir=(pathToAndroidSDK) clean debug

La commande debug va automatiquement signer le fichier avec des paramètres par défaut pour accélérer l'opération.

Améliorer l'émulateur

L'émulateur fourni par défaut dans le SDK rempli certes très bien son devoir, mais est malheureusement très lent. Et les quelques configurations de tuning possibles n'augmentent guère les performances.

L'idéal est de s'orienter vers la mise en place d'une machine virtuelle VirtualBox exécutant le système d'exploitation Android-x86. Pour installer cet outillage, voici un très bon tutoriel sur cette page.

Pour publier le nouveau fichier APK dans la machine virtuelle, il suffit d'exécuter :

// Connexion à la VM
adb connect (IP_DE_LA_VM)
// installation
adb install -r (CHEMIN_DU_APK)

Avec cet outillage, il est possible de tester une nouvelle version de l'application en quelques secondes, là où les outils intégrés aux IDE trainent lors de la re-compilation et publication.

Les commandes utiles

En plus des commandes citées précédemment, il est assez pratique d'en garder quelques unes sous la main, parmi les plus utilisées :

  • adb logcat > C:\log.txt : pour récupérer les logs distants dans un fichier local
  • sqlite3 /data/data/my.package/databases/[nom_bdd] : pour accéder en ligne de commande à la base de données sqlite (sqlite3 est dans le répertoire "tools" du SDK)
  • ddms : toujours dans le répertoire "tools" se trouve l'outil de debug Dalvik, très complet, contenant notamment l'explorateur de fichiers mais également beaucoup d'utilitaires :
    the Dalvik Debug Monitor Server (DDMS), which provides port-forwarding services, screen capture on the device, thread and heap information on the device, logcat, process, and radio state information, incoming call and SMS spoofing, location data spoofing, and more

Vous voilà bien armés, ne reste plus qu'à coder!


Fichier(s) joint(s) :



Piloter Camel avec Quartz et JMX

Cette fois-ci, le besoin est d'ordonnancer l'exécution d'une application Camel via le gestionnaire de tâches Quartz tout en laissant la possibilité de démarrer manuellement les routes à la demande.

Commençons par l'ordonnancement. Admettons que le programme ne doit se lancer qu'à partir de 5 heures du matin en fin de semaine. La syntaxe CRON correspondante est :

* * 5 ? * SAT-SUN

Pour configurer la route initiale avec cette règle, il faut lui spécifier une routePolicy :

@Override
public void configure() throws Exception {
  
 // Quartz
 CronScheduledRoutePolicy startPolicy = new CronScheduledRoutePolicy();
 // ne démarre que le weekend à partir de 5h du matin
 startPolicy.setRouteStartTime("* * 5 ? * SAT-SUN");
 ...
 from("file://...").routePolicy(startPolicy).noAutoStartup().routeId("firstRoute")...
}

Ainsi donc, la route n'est pas démarrée au lancement du contexte mais délègue cette tâche à l'ordonnanceur. (Ne pas oublier d'ajouter la dépendance camel-quartz)

Passons à la mise en place de JMX pour piloter à distance Camel.

Au démarrage de l'application, il faut référencer un bean particulier ayant connaissance du contexte Camel auprès du server JMX de la JVM :

MBeanServer server = ManagementFactory.getPlatformMBeanServer();
MyAgentManagerMXBean mbean = new MyCamelMBean(camelContext);
ObjectName name = new ObjectName("my.jmx.domain.MyDomain:type=MyCamelMBean,name=myCamelMBean");
server.registerMBean(mbean, name);

La paramètre camelContext du bean est une instance du context Camel, par exemple de org.apache.camel.main.Main. Je précise au passage qu'afin de rendre disponible l'interface à JMX, le nom de celle-ci doit être suffixé par MXBean (il s'agit d'une convention JMX). Et voici comment sont écrites l'interface et l'instance du bean mbean

public interface MyAgentManagerMXBean {
 
 /**
  * Start Camel manually, overriding quartz schedule
  * @throws Exception
  */
 public void camelManualStart() throws Exception;

}
public class MyCamelMBean implements MyAgentManagerMXBean {

 private Main camel;
 
 public MyCamelMBean(Main context) {
  camel = context;
 }

 @Override
 public void camelManualStart() throws Exception {
  camel.getRouteBuilders().get(0).getContext().startRoute("firstRoute");
 }
}

Avec cette configuration, il est alors possible, avec n'importe quelle console JMX (ici la JConsole) de démarrer manuellement la route configurée avec Quartz :

J'en profite pour ajouter un exemple permettant de récupérer des informations directement de Camel, par exemple ici le nombre de message traités sur une route :

public long getSourceFilesManagedNb() {
 long result = 0;
 try {
  JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1616/jmxrmi");
  JMXConnector jmxc = JMXConnectorFactory.connect(url);
  MBeanServerConnection server = jmxc.getMBeanServerConnection();
  ObjectName objName = new ObjectName("org.apache.camel:type=routes,name=\"firstRoute\",*");
  List<ObjectName> cacheList = new LinkedList<ObjectName>(server.queryNames(objName, null));
  for (ObjectName objName2 : cacheList) {
   result = (Long) server.invoke(objName2, "getExchangesCompleted", null, null);
  }
 } catch (Exception e) {
  e.printStackTrace();
 }
 return result;
}

Voilà tout!


Fichier(s) joint(s) :