lundi 28 janvier 2013

Debugging à distance d'un serveur JBoss

Il y a peu, une personne de l'équipe dans laquelle je travaille, souhaitait se mettre de debug sur un serveur JBoss de test afin de comprendre un dysfonctionnement.

Pour ceux que ça  intéresse, voici comment faire.
Dans un premier temps, il faut démarrer JBoss en mode debug (la technique dépend de l'environnement utilisé Windows, Distribution Linux...).
Mais attention, par défaut, le serveur attend une connexion sur le port de debug pour se lancer :
-Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n

Il faut donc modifié le suspend pour le mettre à "n" (sauf si le problème se situe au démarrage du war ou ear).
Ensuite, il faut repérer le port de debug (ici 8787).

Lancer Eclipse en debug distant sur le port utilisé, 8787 par défaut (Run -> Debug … -> Remote Java Application).

Ensuite, dans Eclipse, dans la barre d'outil, cliquez sur l'icône de debug (sur la petit flèche) > “Debug Configuration”. Dans “Remote Application Java”, clique droit “New”. Dans l'onglet “Connect”, sélectionnez le projet “integration”. Host : “localhost”. Port : “8787”. Connection type : “Standard (Socket Attach)”. Dans l'onglet “Source”, attachez tous les projets.

mercredi 23 janvier 2013

Les distributions linux

Dans l'univers de GNU/Linux, le nombre impressionnant de distributions a de quoi dérouter.
Toutefois, si on y regarde de plus près il y a 3 distributions majeures.
Ces distributions fonctionne généralement sur du matériel assez récent.

Les autres distributions (comme la très côté en ce moment, Linux Mint) ne sont que des surcouches.

Les distributions majeures

Debian
Debian, une distribution à tout faire (serveur, poste de travail...), qui est développé par une comunauté régie par un contrat social. Elle se caractérise par un très grand nombre d'architectures supportées, une logithèque importante et un cycle de développement relativement long permettant ainsi une bonne stabilité.
Sa qualité en fait un choix privilégié par les professionnels.
Le fait qu'au début, cette distribution ne privilégiait pas l'esthétisme (userfriendly), fait qu'elle a l'image d'une distribution réservée aux experts, ce qui est aujourd'hui complètement erroné.

Slackware
Slackware, qui date de la même époque que Debian, est une distribution très stable, mais aussi très simple en outillage. Le principe de cette distribution est de laisser totalement la main à l'utilisateur, quitte à ce que celui-ci doive ouvrir le capot.
Contrairement aux autres distributions, son gestionnaire de paquets (pkgtool) se distingue par un format généraliste tar.gz.
L'intérêt de cette distribution est justement de permettre à l'utilisateur de modifier le système à la main, sans tous casser.
Elle est fort appréciée sur les serveurs.

RedHat
RedHat est une distribution qui a eu un impact historique particulier. En effet, l'entreprise gérant la distribution est la première a être entrée en bourse. Elle a aussi popularisé le gestionnaire de paquets avec gestion de dépendances (format RPM qui est très largement utilisé aujourd'hui).
Cette distribution généralise à contribué au succès de Linux.
C'est une distribution généralise.

Les autres distributions


D'autres distribution n'ont, elles, aucun lien avec les versions citées précédemment (Gentoo, Arch Linux), mais toujours pour du matériel assez récent, sauf...

SliTaz
La distribution SliTaz est un peu une distribution extraterrestre dans le monde GNU/Linux. En effet, son but est d'être très simple et très légère.
Elle fonctionne parfaitement sur de très vielle machine (testé avec un carte graphique 8Mo et 256Mo de RAM).
Par contre, il faudra oublier vos habitudes. Pas de logiciel lourd comme FireFox, LibreOffice.
C'est une distribution généraliste et propose des logiciels pour après tous les besoins. Par contre, ce sont rarement des logiciels répandu, car trop lourd.

vendredi 18 janvier 2013

Fusionner deux images en Java

La fusion de deux images en Java est assez simple.

Il faut transformer les deux images en BufferedImage.

Ensuite, rien de plus simple :
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

// Buffer image with transparancy support (alpha chanel)
final BufferedImage image = new BufferedImage(20, 20, BufferedImage.TYPE_INT_ARGB) ;
final BufferedImage tilePicture = ....
// Graphic
final Graphics2D g2 = image.createGraphics() ;

g2.drawImage(tilePicture, object.getX(), object.getY(), null) ;

Le null peut être remplacé par un java.awt.image.ImageObserver qui permet d'être notifié lorsque l'image est prête.

lundi 14 janvier 2013

Transparence dans les images Java

Java permet de créer nativement des images transparentes.

Lorsqu'une image est créée, si le paramètre BufferedImage.TYPE_INT_ARGB est indiqué, l'image supportera l'alpha chanel, soit la gestion de transparence.

Par défaut, toute l'image est transparente.

Il peut être intéressant de créer un couleur de transparence qui sera mis dans un tableau par exemple.

Ci dessous voici un exemple complet d'image transparente et de création de couleur transparente :
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

// Buffer image with transparancy support (alpha chanel)
final BufferedImage image = new BufferedImage(20, 20, BufferedImage.TYPE_INT_ARGB) ;

// Graphic
final Graphics2D g2 = image.createGraphics() ;

// Create color. True is to say the color value contain alpha chanel
// Here, alpha chanel is 0x00
Color c = new Color(0x00FFFFFF, true) ;

g2.setColor(color) ;

final Rectangle rect = new Rectangle(0, 0, 19, 19) ;

// All picture is transparent. Realy not necessary because at create time all picture is transparent
g2.fill(rect) ;

// No transpancy
Color c = new Color(0x000000) ;

// Draw line
g2.drawLine(0, 0, 19, 19) ;

vendredi 11 janvier 2013

Création de plugin maven [2/2]

Dans l'article précédent, il a été vu comment créer un plugin maven très simple.

Il va être abordé un plugin pas plus difficile, mais avec quelques différences (nécessite un projet, paramètre obligatoire...).

Deuxième plugin maven


Dans le même projet, une classe qui liste un répertoire va être créé :
package org.test.maven.plugin;

import java.io.File;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;

/**
 * 
 * @author Emeric MARTINEAU
 * @goal listDir
 * @requiresProject true
 */
public class ListDirectory extends AbstractMojo {

 /**
  * @parameter default-value="${project}"
  * @required
  * @readonly
  */
 private MavenProject project; 
 
 /**
  * @required
  * @parameter expression="${dir}"
  */
 private String dir; 
 
 /* (non-Javadoc)
  * @see org.apache.maven.plugin.Mojo#execute()
  */
 @Override
 public void execute() throws MojoExecutionException, MojoFailureException {
  final File directory = new File(dir) ;
  
  if (!directory.exists()) {
   getLog().error(dir.concat(" doesn't exists !")) ;
   
   return ;
  }  
  
  // List file of directory
  final File[] fileList = directory.listFiles() ;
  
  File currentFile ;
  
  // For each file
  for(int index = 0; index < fileList.length; index++) {
   currentFile = fileList[index] ;
   
   if (currentFile.isDirectory()) {
    // Current file is directory
    getLog().info("<DIR> ".concat(currentFile.getName())) ;
   } else {
    getLog().info("      ".concat(currentFile.getName())) ;
   }
  }
  
  getLog().info("Basedir = " + project.getBasedir().getAbsolutePath()) ;
 }
}
Le goal est donc listDir et la classe nécessite un projet @requiresProject true.

Le paramètre dir est rendu obligatoire par la présence dans la java doc de @required.

Le paramètre project représente le projet maven (pom.xml).

Pour fonctionner, la dépendence suivante doit être ajoutée :
<dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-core</artifactId>
    <version>3.0.3</version>
    <scope>compile</scope>
</dependency>

Voici le résutat si lancé sans pom :
mvn org.test.maven.plugin:test-plugin-maven:listDir

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.766s
[INFO] Finished at: Thu Dec 13 11:06:23 CET 2012
[INFO] Final Memory: 4M/245M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.test.maven.plugin:test-plugin-maven:1.0.0-SNAPSHOT:listDir (default-cli): Goal requires a project to execute but there is no POM in this directory (D:\Logiciels\Apache\apache-maven-3.0.3\bin). Please verify you invoked Maven from the correct directory. -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MissingProjectException
Voici le résultat si lancé avec un pom mais sans le paramètre :
mvn org.test.maven.plugin:test-plugin-maven:listDir

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building toto 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- test-plugin-maven:1.0.0-SNAPSHOT:listDir (default-cli) @ toto ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.359s
[INFO] Finished at: Thu Dec 13 11:17:21 CET 2012
[INFO] Final Memory: 4M/245M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.test.maven.plugin:test-plugin-maven:1.0.0-SNAPSHOT:listDir (default-cli) on project toto: The parameters 'dir' for goal org.test.maven.plugin:test-plugin-maven:1.0.0-SNAPSHOT:listDir are missing or invalid -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginParameterException
Voici le résultat lancé correctement :
mvn org.test.maven.plugin:test-plugin-maven:listDir -Ddir=/temp/

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building toto 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- test-plugin-maven:1.0.0-SNAPSHOT:listDir (default-cli) @ toto ---
[INFO]       1.jn1
[INFO]       intro.jn1
[INFO] <DIR> jill-binaries
[INFO] <DIR> jill-tiles
[INFO] <DIR> MAVEN
[INFO]       test.png
[INFO] Basedir = /temp
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.578s
[INFO] Finished at: Thu Dec 13 11:17:54 CET 2012
[INFO] Final Memory: 6M/309M
[INFO] ------------------------------------------------------------------------

L'objet MavenProject


La partie de code de la classe :
/**
 * @parameter default-value="${project}"
 * @required
 * @readonly
 */
private MavenProject project;
permet de récupéré via la propriété maven ${project} le projet maven.
Il est donc possible d’accéder à toute les propriétés du projet.
L'objet MavenProject est disponible dans la librairie maven-core.

Il ne reste plus qu'à se reporter à la documentation officiele : Maven - Guide to Developing Java Plugins.

lundi 7 janvier 2013

Création de plugin maven [1/2]

Maven permet de facilement (une fois son fonctionnement compris) de construire, livrer, installer un projet.

Maven fonctionne sur la base de plugin. Toutefois, il n'est pas rare qu'un besoin particulier s'exprime et qu'aucun plugin n'y réponde.
Il faudra alors écrire soit même un plugin.

L'écriture de plugin est relativement aisée. C'est plutôt ce que doit faire le plugin qui n'est pas trivial.

Il existe deux types de plugin. Celui qui nécessite un projet pour s'exécuter (donc un pom.xml), comme par exemple maven-compiler-plugin.
Et celui qu'il est possible de lancer sans projet.

Premier plugin maven

Pouc commencer, un plugin sans projet pas être créé. Il affichera un message dans les logs. Ce message sera paramètrable (donc facultatif).

Voici la classe du plugin :
package org.test.maven.plugin;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;

/**
 * 
 * @author Emeric MARTINEAU
 * @goal hello
 * @requiresProject false
 */
public class HelloWorld extends AbstractMojo {

 /**
  * @parameter expression="${hello.str}" default-value="Hello World!"
  */
 private String helloStr;  
  
 @Override
 public void execute() throws MojoExecutionException, MojoFailureException {
  getLog().info(helloStr) ;
 }

}
Elle hérite nécessairement de la classe org.apache.maven.plugin.AbstractMojo.
Sera implémenté la méthode execute().

La configuration du plugin se fait via la JavaDoc et certaines balises @.
Ici pour la classe il y a le goal définit par @goal hello et si un projet est requis @requiresProject false.
Il est possible d'indiquer la phase avec @phase.

La classe accèpte un paramètre hello.str configuré avec @parameter expression="${hello.str}" default-value="Hello World!".
Il peut être valoriser en ligne de commande via -Dhello.str=xxxx ou dans un pom avec :
<configuration>
 <hello.str>Bonjour le monde !</hello.str>
</configuration>
Si aucun paramètre n'est communiqué, le paramètre prendra la valeur Hello World!.

Et son pom associé :
<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>org.test.maven.plugin</groupId>
    <artifactId>test-plugin-maven</artifactId>
    <packaging>maven-plugin</packaging>
    <version>1.0.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-plugin-api</artifactId>
            <version>3.0.4</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugin</groupId>
                <artifactId>maven-plugin-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <goalPrefix>testPluginMaven</goalPrefix>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Exemple d'exécution sans paramètre :
mvn org.test.maven.plugin:test-plugin-maven:hello

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- test-plugin-maven:1.0.0-SNAPSHOT:hello (default-cli) @ standalone-pom ---
[INFO] Hello World!
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.297s
[INFO] Finished at: Thu Dec 13 11:01:56 CET 2012
[INFO] Final Memory: 4M/245M
[INFO] ------------------------------------------------------------------------
Exemple d'exécution avec paramètre :
mvn org.test.maven.plugin:test-plugin-maven:hello -Dhello.str="bonjour ca va ?"

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- test-plugin-maven:1.0.0-SNAPSHOT:hello (default-cli) @ standalone-pom ---
[INFO] bonjour ca va ?
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.234s
[INFO] Finished at: Thu Dec 13 11:55:40 CET 2012
[INFO] Final Memory: 6M/309M
[INFO] ------------------------------------------------------------------------
Le fait que le plugin est exécuté sans pom se remarque à standalone-pom juste au dessus du texte affiché par le plugin.