Archives pour la catégorie ‘Développement’

Roundcubemail : plugin rc-vacation 0.5

La version 0.5 du plugin rc-vacation est disponible. Outre la correction de quelques bugs, un driver d’intégration avec le panel de gestion Plesk est disponible. Cette version est compatible avec la version 0.7.1 de RoundCube.

Dépôt Git : http://github.com/bhuisgen/rc-vacation
Tarball : rc-vacation-0.5.tar.gz

Nano : activer la coloration syntaxique

L’éditeur de texte nano supporte comme tout autre éditeur la coloration syntaxique. Pour l’activer, vérifiez où sont stockées les templates de format (/usr/share/nano ou équivalent) et chargez-les dans votre fichier de préférence ~/.nanorc :

# more .nanorc
set autoindent
include "/usr/local/share/nano/nanorc.nanorc"
include "/usr/local/share/nano/c.nanorc"
include "/usr/local/share/nano/html.nanorc"
include "/usr/local/share/nano/patch.nanorc"
include "/usr/local/share/nano/man.nanorc"
include "/usr/local/share/nano/perl.nanorc"
include "/usr/local/share/nano/python.nanorc"
include "/usr/local/share/nano/java.nanorc"
include "/usr/local/share/nano/sh.nanorc"

Et voilà le rendu sur un fichier Perl :

Glassfish 3 : créer un pool de connexions JDBC

Cet exemple couvre la création d’un pool de connexions JDBC pour un serveur MySQL,

En premier lieu, ne pas oublier d’installer le driver JDBC de MySQL dans le domaine d’exécution :

$ cd $GLASSFISH_HOME
$ ./bin/asadmin stop-domain
$ cp ~/mysql-connector-java-5.1.13-bin.jar glassfish/domains/domain1/lib/
$ ./bin/asadmin start-domain

La création du pool de connexions (en veillant aux caractères d’échappement dans l’URL) :

$ ./bin/asadmin create-jdbc-connection-pool --datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlDataSource --restype javax.sql.DataSource --property User=myuser:Password=mypwd:URL=jdbc\\:mysql\\://127.0.0.1/mydb mydb_pool
Command create-jdbc-connection-pool executed successfully.

Un test rapide pour valider la connexion au serveur MySQL :

$ ./bin/asadmin ping-connection-pool mydb_pool
Command ping-connection-pool executed successfully.

Reste à créer la ressource jdbc/mydb à utiliser dans l’application Java :

$ ./bin/asadmin create-jdbc-resource --connectionpoolid=mydb_pool jdbc/mydb
Command create-jdbc-resource executed successfully.

Eclipse : utiliser votre script Ant depuis l’IDE

Pour utiliser votre script Ant depuis l’interface d’Eclipse, vous pouvez ajouter un Ant Builder à votre projet afin de remplacer le builder par défaut Java Builder. Une fois votre build.xml écrit, il faut configurer le builder Ant afin de faire correspondre les cibles aux actions de l’interface graphique : Build Project, Clean, Build Automatically

Pour ce faire, éditez les propriétés de votre projet et sélectionner la rubrique Builders. Ajoutez un builder de type Ant Builder et choisissez un nom lié au projet en cours (afin de pouvoir travailler sur plusieurs projets par la suite).

  • La première étape de configuration consiste à sélectionner votre fichier build.xml et son répertoire de travail.

  • Le second onglet permet de configurer le rafraîchissement du projet et de la vue Project Explorer, suite aux nouveaux fichiers  générés durant le build.

  • Les différents évènements de l’interface sont configurés dans l’onglet Targets :
    • After clean correspond au premier évènement de build lancé suite à un nettoyage par Build / Clean… La cible normale de compilation convient à cet usage.
    • Manual Build est levé par Build / Build Project. Si aucun évènement ne s’est produit suite au nettoyage, ce ne sera pas cet évènement qui sera levé mais After clean.
    • Auto-build correspond à l’évènement lancé par l’IDE lorsqu’une modification est détectée dans les sources (ou comment ruiner son disque dur rapidement). Vous pouvez le désactiver en ne spécifiant aucune cible ou le faire par l’interface en décochant Build / Build Automatically.
    • Clean correspond à la cible exécutée par Build / Clean…

Vous pouvez spécifier plusieurs cibles par évènement. Elles seront toutes exécutées par  ordre. Si  vos cibles ont des dépendances, elles seront également exécutées. Dans un tel cas, seule la dernière cible de la chaîne est nécessaire. Si aucune cible n’est sélectionnée, l’interface d’Eclipse ne répondra pas.

  • Dernier point, il faut désactiver le builder d’Eclipse Java Builder et confirmer l’avertissement.

Si vous souhaitez avoir un accès rapide à vos cibles secondaires, vous pouvez faire appel à la vue Ant et y ajouter vos scripts.

PHP : gestion FastCGI avec PHP-FPM

Le port de PHP 5.3.3 est disponible ! Au programme de cette nouvelle version, l’intégration de PHP-FPM, un gestionnaire de processus PHP/FastCGI.

PHP-FPM permet de gérer plusieurs pools de processus, chacun possédant ses propres règles : gestion statique/dynamique (pour s’adapter à la charge du serveur), limites mini/maxi de processus actifs/en attente, type d’écoute par socket Unix ou TCP/IP (pour déporter l’exécution sur un serveur distinct), nombre maxi de requêtes par processus avant extinction. Le redémarrage complet du pool est également supporté en cas de crash suite à une fuite mémoire. Le recours à un outil équivalent mais limité en option, tel que spawn-fcgi n’est donc plus nécessaire (référez-vous à mes articles à son sujet : ici et ici). J’oubliais l’utilisation d’un cache de code PHP tel que APC ou Xcache est possible vu que les processus php-fpm ne sont pas détruits après chaque requête.

Je vous fais part des étapes nécessaires à sa mise en place, effectuées ici sous FreeBSD 8.1 & Nginx.

  • Configuration de PHP

Il faut s’assurer d’activer le flag de compilation de PHP-FPM :

# cd /usr/ports/lang/php5
# make config
# make install

On oublie pas l’extension de sécurité suhosin et le cache APC :

# cd /usr/ports/security/php-suhosin
# make install
# cd /usr/ports/www/pecl-APC
# make install

Une petite vérification de routine :

# php -v
PHP 5.3.3 with Suhosin-Patch (cli) (built: Aug  9 2010 21:34:21)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
 with Suhosin v0.9.32.1, Copyright (c) 2007-2010, by SektionEins GmbH
  • Configuration de PHP-FPM

Le module dispose de son propre fichier de configuration /usr/local/etc/php-fpm.conf :

[global]
pid = /var/run/php-fpm.pid
;error_log = /var/log/php-fpm.log
[www]
# socket
listen = /tmp/php-fpm.sock
listen.owner = www
listen.group = www
listen.mode = 0666
# user ID/GID
user = www
group = www
# pool
pm = dynamic
pm.max_children = 20
pm.start_servers = 8
pm.min_spare_servers = 4
pm.max_spare_servers = 8

Est configuré un pool de processus dynamique avec un maximum de 20 processus PHP, avec écoute par socket UNIX, le tout limité au compte utilisateur du serveur web www. Le démon peut à présent être lancé :

# echo "php_fpm_enable="YES" >> /etc/rc.conf
# /usr/local/etc/rc.d/php-fpm start
Starting php_fpm.

Le pool PHP devrait être en exécution :

# su -m www
www# ps aux|grep php
www  68220  0.6  2.3 110152 48216  ??  SJ   11:56PM   0:00.95 /usr/local/sbin/php-fpm
www  68219  0.0  0.6 99912 12540  ??  IJ   11:56PM   0:00.00 /usr/local/sbin/php-fpm
www  68221  0.0  0.6 99912 12540  ??  IJ   11:56PM   0:00.00 /usr/local/sbin/php-fpm
www  68222  0.0  0.6 99912 12540  ??  IJ   11:56PM   0:00.00 /usr/local/sbin/php-fpm
www  68223  0.0  0.6 99912 12540  ??  IJ   11:56PM   0:00.00 /usr/local/sbin/php-fpm
www  68224  0.0  0.6 99912 12540  ??  IJ   11:56PM   0:00.00 /usr/local/sbin/php-fpm
www  68225  0.0  0.6 99912 12540  ??  IJ   11:56PM   0:00.00 /usr/local/sbin/php-fpm
www  68226  0.0  0.6 99912 12540  ??  IJ   11:56PM   0:00.00 /usr/local/sbin/php-fpm
www  68402  0.0  0.1  9092  1172   1  R+J  12:00AM   0:00.00 grep php
  • Configuration de Nginx

Le module FastCGI doit être configuré pour utiliser le pool. J’utilise pour ce faire un fragment de configuration que j’inclue dans chaque vhost où PHP est nécessaire :

# cd /usr/local/etc/nginx/
# more fragments/php.conf
fastcgi_pass   unix:/tmp/php-fpm.sock;
fastcgi_index  index.php;
fastcgi_param  SCRIPT_FILENAME    $request_filename;
include        fastcgi_params;

Le nom et le type de socket doit correspondre ici à ce qui a été déclaré dans la configuration de PHP-FPM.

# more vhosts/site_fr.conf
server {
 listen 172.16.0.5:80;
 server_name www.site.fr;
 root /usr/local/www/site.fr/www/html;
 index index.php;

 location ~ \.php$ {
  include fragments/php.conf;
 }
}

Nginx peut enfin être redémarré  :

# /usr/local/etc/rc.d/nginx restart
Performing sanity check on nginx configuration:
the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
configuration file /usr/local/etc/nginx/nginx.conf test is successful
Stopping nginx.
Waiting for PIDS: 89603.
Performing sanity check on nginx configuration:
the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
configuration file /usr/local/etc/nginx/nginx.conf test is successful
Starting nginx.

L’exécution des scripts PHP est à présent assurée par le pool PHP-FPM.

Java : JAX-WS & exception utilisateur

La gestion des exceptions utilisateur au sein d’un webservice utilisant l’API JAX-WS doit respecter quelques contraintes afin de  transmettre l’ensemble des informations au client SOAP.

Voici un exemple pour une classe d’exception UserFault dont les détails optionnels sont implémentés par la classe UserFaultDetail :

@WebFault
public class UserFault extends Exception {
	private static final long serialVersionUID = 1L;
	private UserFaultDetail userFaultDetail;

	/**
	 * Constructs an <code>UserFault</code> object.
	 *
	 * @param message
	 *            the error message.
	 * @param userFaultDetail
	 *            the error details.
	 */
	public UserFault(String message, UserFaultDetail userFaultDetail) {
		super(message);
		this.userFaultDetail = userFaultDetail;
	}

	/**
	 * Constructs an <code>UserFault</code> object.
	 *
	 * @param message
	 *            the error message.
	 * @param userFaultDetail
	 *            the error details.
	 * @param cause
	 *            the error cause.
	 */
	public UserFault(String message, UserFaultDetail userFaultDetail,
			Throwable cause) {
		super(message, cause);
		this.userFaultDetail = userFaultDetail;
	}

	/**
	 * Returns the error details.
	 *
	 * @return the error details.
	 */
	public UserFaultDetail getFaultInfo() {
		return userFaultDetail;
	}
}
public class UserFaultDetail {
	public static final int ERROR_UNKNOWN = 0;
	public static final int ERROR_INVALIDAPIKEY = -1;
	private int code;

	/**
	 * Constructs a new <code>UserFaultDetail</code> object.
	 */
	public UserFaultDetail ()
	{
		this.code = UserFaultDetail.ERROR_UNKNOWN;
	}

	/**
	 * Constructs a new <code>UserFaultDetail</code> object.
	 * @param code the code of the fault.
	 */
	public UserFaultDetail (int code)
	{
		this.code = code;
	}

	/**
	 * Returns the code of the fault.
	 * @return the code.
	 */
	public int getCode() {
		return code;
	}

	/**
	 * Sets the code of the fault.
	 *
	 * @param code
	 */
	public void setCode(int code) {
		this.code = code;
	}
}

Mac OS X : Java 6 pour Mac à CPU 32 bits

Le port de Java 6 pour les Macs à CPU 32 bits (Intel CoreDuo 2006) est disponible au téléchargement sur cette page :

http://landonf.bikemonkey.org/static/soylatte/

eZ Publish : traduction des fichiers PHP UTF-8

Ayant participé à la migration ezPublish 4 d’un site bancaire luxembourgeois au cours de l’année précédente, mon collègue m’avait reporté un problème concernant l’outil de traduction ezlupdate chargé d’extraire les chaînes à internationaliser. L’outil fourni par eZ à cette époque n’acceptait pas l’extraction de chaînes depuis des fichiers PHP au format UTF-8, alors qu’il le supportait  au niveau des templates.

J’ai donc dû modifier les sources de la version Qt 3 et générer un nouveau parseur. L’outil a rempli son rôle et je vous en fait part : ezlupdate-source-hb-20090217.tar.gz

Pour compiler les sources :

cd /<ezroot>/support
tar czf ezlupdate-source-hb-20090217.tar.gz
cd ezlupdate-HB
qmake ezlupdate.pro
make

N’oubliez pas d’installer Qt 3 et ses outils de développement pour la commande qmake. Pour l’utiliser, il faut ajouter l’option –utf8 pour pouvoir créer le fichier de traduction :

/bin/linux/ezlupdate -e extension/test/ -no eng-GB --utf8

Note : la nouvelle version d’ezlupdate basée sur Qt 4 semble à présent gérer les scripts PHP UTF-8 – quasiment un an après – mais il subsiste des problèmes avec les traductions commentées et les traductions dans les javascripts.

Java : analyser le heap d'une application

La version 1.6 de la machine Java de Sun intégre un outil permettant d’analyser le heap d’une application : jhat. Il permet par exemple de vérifier quelles sont les instances vivantes des objets dans le heap, le nombre de créations d’instances pour un object donné, un historique de création … Bref, un outil simple pour profiler un minimum son soft et éviter les messages de ce genre (c’est pour l’exemple) :

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

En premier lieu sous Mac OS X, cet outil ne fonctionne pas out of the box, il faut installer un moteur JavaScript (celui d’Apple lance une exception au lancement de jhat). Pour installer un autre moteur JS, téléchargez les 2 archives suivantes :
- JSR-223′s engines : https://scripting.dev.java.net/files/documents/4957/37593/jsr223-engines.zip
- Rhino : http://www.mozilla.org/rhino/download.html

$ sudo cp ~/Desktop/jsr223-engines/javascript/build/js-engine.jar
 /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/lib/ext/
$ sudo cp ~/Desktop/rhino1_7R2/js.jar
 /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/lib/ext/

Le nouveaux moteur JS Rhino doit à présent être listé par jrunscript :

$ /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Commands/jrunscript -q
Language EmbeddedECMAScript 1.6 implemention "Mozilla Rhino" 1.6 release 2
Language AppleScript 2.0.1 implemention "AppleScriptEngine" 1.0
Language ECMAScript 1.6 implemention "Mozilla Rhino" 1.6R7

Pour lancer l’analyse du heap d’une application, il est nécessaire de récupérer son PID par jps, pour le passer à jmap qui va dumper le heap dans un fichier. Une fois créé, on peut l’analyser avec jhat :

$ /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Commands/jps
22746 Jps
22716 Application
45737

$ /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Commands/jmap
 -dump:format=b,file=dump.dat 22716
Dumping heap to /Users/bhuisgen/dump.dat ...
Heap dump file created

$ /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Commands/jhat -J-Xmx512m dump.dat
Reading from dump.dat...
Dump file created Sun May 17 18:22:24 CEST 2009
Snapshot read, resolving...
Resolving 160010 objects...
Chasing references, expect 32 dots................................
Eliminating duplicate references................................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

Rendez-vous @ http://127.0.0.1:7000 pour consulter les résultats : nombres d’instances créées, histogramme de création, et un query browser OQL qui permet de faire ses propres requêtes d’analyse (à tester absolument).

Quelques screenshots de démo :

jhat-main

jhat-instance_counts

jhat-heap_histogram

jhat-oql1

jhat-oql2

Java : analyse de code et détection de bugs

S’il y a bien un logiciel à conserver dans sa boite à outils, il s’agit d’un analyseur de code. En phase de stabilisation d’un de mes logiciels, j’en ai profité pour passer un coup de FindBugs!, l’analyseur et détecteur de bugs open-source pour Java. Il opère directement sur le byte-code à la recherche d’erreurs de programmation et si les sources sont disponibles, il marque son  endroit exact. Il dispose de son propre frontend graphique, mais un plugin Eclipse existe. L’intégration à un projet peut également se faire par le biais d’une tâche Ant.

Je me suis donc retrouvé avec à peu près 80 problèmes tous types confondus (sur les 40 000 lignes du projet, je trouve çà honnête), sachant qu’il y a toujours des faux-positifs (au nombre de 60). Pêle-mêle, il a réussi à détecter :

  • des nettoyages de ressources inutiles dans des blocs de traitement d’exception.
  • des itérateurs inadaptés par exemple lors d’une itération de Map, en me conseillant l’utilisation du bon (screenshot 1).
  • des problèmes de synchronisation d’ accès concurrents.
  • un bloc synchronized vide, dans mon cas un faux-positif (screenshot 2).
  • un appel à wait () hors d’une boucle d’itération, idem faux-positif.
  • l’utilisation de variables inutiles.

Bref, l’outil relève des faux-positifs – c’est quelque peu obligatoire – mais son utilité n’en n’est pas atteinte !

Site officiel : http://findbugs.sourceforge.net/
Source de téléchargement du plugin Eclipse : http://findbugs.cs.umd.edu/eclipse/
Autres outils du même type : MPD, CheckStyle…

findbugs_01findbugs_02

Haut de page