J2EE7 – Pom minimal

By , 15/07/2014

J’ai souvent utilisé l’archetype Maven jboss-javaee6-webapp-archetype pour commencer un projet J2EE6. En cherchant sur internet la version suivante pour un projet de type J2EE7, j’ai découvert ce fichier pom.xml minimaliste :

<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>groupId</groupId>
    <artifactId>artifactId</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <finalName>${artifactId}</finalName>
    </build>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </properties>
</project>

Voici la source : http://www.adam-bien.com/roller/abien/entry/essential_maven_pom_for_javaee.

Pour compléter ce fichier il est possible d’ajouter un des nombreux boms proposés par le projet wildfly en version 8.0.0.Final (https://github.com/wildfly/boms) :

  • jboss-javaee-7.0-with-all
  • jboss-javaee-7.0-with-hibernate
  • jboss-javaee-7.0-with-hibernate3
  • jboss-javaee-7.0-with-infinispan
  • jboss-javaee-7.0-with-logging
  • jboss-javaee-7.0-with-resteasy
  • jboss-javaee-7.0-with-security
  • jboss-javaee-7.0-with-tools
  • jboss-javaee-7.0-with-transactions

Par exemple :

<dependencyManagement>
    <dependencies>
        <dependency>
           <groupId>org.wildfly.bom</groupId>
           <artifactId>jboss-javaee-7.0-with-all</artifactId>
           <version>8.0.0.Final</version>
           <type>pom</type>
           <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Au final, je n’ai pas trouvé l’archetype que je souhaitais, mais je suis tout de même tombé sur une bonne astuce pour débuter un projet J2EE7 très rapidement.

Kingsoft – Installer sur Ubuntu

By , 14/07/2014

Pour installer cette suite bureautique sous Ubuntu, il faut télécharger manuellement le package debian à l’adresse suivante : http://wps-community.org/download.html.

La commande pour installer : sudo dpkg -i kingsoft-office_9.1.0.4280~a12p4_i386.deb

La commande pour vérifier l’installation : sudo dpkg -l | grep kingsoft-office

La commande pour désinstaller : sudo dpkg -r  kingsoft-office:i386

Kingsoft Office – Configurer un nouveau dictionnaire

By , 14/07/2014

Après l’installation de la suite bureautique Kingsoft Office, j’étais très enthousiasmé (je le suis toujours d’ailleurs). Enfin une suite bureautique gratuite proposant les menus de type rubans comme les dernières versions de la suite bureautique de Microsoft. En plus des rubans, l’interface est propre et bien présentée.

Le problème : tous mes mots étaient soulignés de rouge, marqueur de faute d’orthographe. Comme il n’est pas envisageable d’utiliser une suite bureautique sans correction orthographique et encore moins une correction orthographique erronée, cet article va expliquer comment configurer le dictionnaire.

Ajouter un nouveau dictionnaire

Par défaut les dictionnaires installés ne sont pas très nombreux. Pour ajouter un dictionnaire il faut se diriger dans les options de Kingsoft disponible dans le menu principal (cliquer sur le bouton ). Dans la fenêtre ainsi ouverte, il faut sélectionner “Spelling” puis cliquer sur le bouton “custom dictionaries…” :

Dans la fenêtre suivante, cliquer sur le bouton “add…” afin de procéder à la sélection d’un nouveau dictionnaire. Pour information, ils sont disponibles en téléchargement gratuit à l’adresse suivante : http://wps-community.org/download/dicts/

Paramétrer la langue d’un document

Après l’installation d’un dictionnaire, il faut l’utiliser. Pour cela il faut ouvrir un document Word et se diriger dans le menu (ruban) “Review”, un bouton “Set Spellcheck Language” vous permet de paramétrer le langage par défaut du document en cours d’édition.

Linux – Configurer une passerelle par défaut

By , 21/04/2014

Voici comment configurer une passerelle par défaut pour une interface réseau sous Linux. La commande à connaître est route. Elle permet de visualiser et éditer la table de routage d’une machine Linux.

Afficher la table de routage

La commande est la suivante :

$ route

Le résultat peut ressembler à cela :

$ route
Kernel IP routing table
Destination  Gateway     Genmask         Flags Metric Ref Use  Iface
192.168.1.0  *           255.255.255.0   U     0      0   0    eth0
default      routeur     0.0.0.0         UG    0      0   0    eth0

Pour remplacer les noms par les adresses IP il faut utiliser le switch -n.

Ajouter une gateway (passerelle) par défaut

Il faut être connecté avec le compte root. La commande a utilisé est la suivante :

route add default gw {IP-ADDRESS} {INTERFACE-NAME}

Il est possible d’utiliser une adresse IP ou un nom de machine :

# route add default gw 192.168.1.254 eth0

# route add default gw router eth0

Configuration automatique

Sur une distribution centOs ou RedHad, il est possible d’éditer le fichier de configuration suivant pour paramétrer définitivement la passerelle par défaut : /etc/sysconfig/network. Dans ce cas il faut ajouter la ligne GATEWAY=<adresse IP de la passerelle>.

Pour une distribution comme Ubuntu, chaque interface réseau statique (pas de serveur DHCP) est configurée via le fichier : /etc/network/interfaces

JSF2.2 – Hello world Ajax

By , 17/03/2014

Dans cet article il est proposé de développer une petite application JSF 2.2 avec un rechargement Ajax. Il existe beaucoup d’exemples qui utilisent par simplicité des objets en session. Le problème dans ce cas c’est que l’on ne comprend pas forcément l’importance des scopes et de la structure que l’on peut utiliser lors d’un développement en prenant en compte les problématiques de production classiques (limiter et simplifier la taille et l’utilisation de la mémoire).

Vue d’ensemble et configurations

Dans cet exemple en conditions réelles nous pouvons séparer les objets Java en trois catégories d’où les trois packages suivant :

  • Le modèle (les données dans le modèle MVC) : dans l’exemple un simple POJO, dans une application réelle cela peut être une entité JPA.
  • Le contrôleur (le contrôleur dans le modèle MVC) : dans l’exemple un simple POJO, dans une application réelle cela peut aussi être une EJB.
  • Le DAO pour l’accès aux données. Dans ce cas il s’agit d’un producer.

Le fichier XHTML représente la vue dans le modèle MVC. Les fichiers de configuration restent vides.

Le model

Dans cet exemple il s’agit d’un simple POJO avec une variable d’instance de type String pour sauvegarder le nom de l’utilisateur.

package org.eiw.model;

/**
 * Dans un cas réel, ce bean pourrait être un objet persistant.
 *
 */
public class HelloBean {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

Le producer

Le producer, est un POJO enregistré dans le scope Request afin de limiter le nombre d’objets en session. C’est lui qui se charge de délivrer le modèle aux autres parties de l’application, dont la vue. Il y a deux méthodes d’initialisations :

  • @PostConstruct : méthode qui est exécutée automatiquement à la création de l’objet donc à chaque nouvelle requête HTTP.
  • @Observes : méthode qui est exécuté lorsqu’un événement de type HelloBean est lancé. Elle remplace la valeur par défaut du modèle par la valeur de l’objet passé en paramètre.
package org.eiw.data;

import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.event.Observes;
import javax.enterprise.event.Reception;
import javax.enterprise.inject.Produces;
import javax.inject.Named;

import org.eiw.model.HelloBean;
/**
 * Le producer es dans le scope Request,
 * il sera recréé à chaque nouvelle requete HTTP.
 */
@RequestScoped
public class HelloWorldProducer {
    private HelloBean myHelloBean;
    /**
         * La méthode qui produit l'objet de données vis à vis de la page XHTML.
         */
    @Named
    @Produces
    public HelloBean getMyHelloBean() {
        return myHelloBean;
    }
    /**
     * Initialise myHelloBean via un évènement.
     * Méthode observeur qui s'éxécute lorsqu'un évènement
     * de type HelloBean est lancé.
     * @param helloBean Le paramètre de l'évènement détecté.
     */
    public void myHelloBeanObserver(
            @Observes(notifyObserver = Reception.IF_EXISTS)
                HelloBean helloBean) {
        myHelloBean = helloBean;
    }

    /**
     * La méthode qui initialise l'objet,
         * à chaque nouvelle requête HTTP.
         */
    @PostConstruct
    public void initMessage() {
        myHelloBean = new HelloBean();
    }
}

Le contrôleur

Cet objet est annoté avec @Model. Cela lui permet d’être enregistré dans le scope Request et d’être “outjecter” dans le contexte CDI. Il est donc visible dans la vue. Il possède une méthode public que la vue peut appeler. Il a aussi une variable d’instance de type javax.enterprise.event.Event qui va permettre de déclencher un événement de type HelloBean et donc de prévenir le producer que l’objet myHelloBean doit être initialisé avec la méthode @Observes.

package org.eiw.controller;

import javax.enterprise.event.Event;
import javax.enterprise.inject.Model;
import javax.inject.Inject;

import org.eiw.model.HelloBean;

/**
 * Controller qui va traiter les demandes des vues.
 * L'annotation est utilisée pour :
 *  - Positionner l'objet dans le scope Request
 *  - Outjecter l'objet dans le contexte d'injection CDI
 *  - Pouvoir référencer l'objet dans la vue XHTML
 */
@Model
public class HelloController {

    /**
     * Injection d'un evènement pour pouvoir prévenir
     * le producer que l'objet myHelloBean doit être modifier.
     */
    @Inject
    private Event<HelloBean> helloBeanEventSrc;

    /**
     * Action pour traiter la soumission du formulaire.
     * @param helloBean Cet instance vient de l'IHM.
     */
    public void modifierBean(HelloBean helloBean) {
        // Lancement de l'évènement de type HelloBean pour
        // provoquer l'exécution de la méthode observeur
        // pour mettre à jour le bean HeeloBean
        helloBeanEventSrc.fire(helloBean);
    }
}

La vue

Dans le fichier XHTML, il est important de remarquer que le composant de saisi et le bouton d’action sont encapsulés dans un formulaire (<h:form/>). Dès qu’un composant fait appel à une action ou un listner il faut l’encapsuler dans un formulaire.  Sinon, la vue ne peut pas interagir avec le code Java. Cela provient de  la façon de travailler de JSF, en effet, toutes les interactions entre XHTML et Java passent par la soumission d’un formulaire en POST.

En revanche, la partie de la page qui se rafraîchit n’est pas nécessairement dans un formulaire.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
	<h:form>
		Saisir votre nom :
		<h:inputText value="#{myHelloBean.name}" />
		<h:commandButton value="valider">
			<f:ajax render="message" execute="@form"
				listener="#{helloController.modifierBean(myHelloBean)}" />
		</h:commandButton>
	</h:form>
	<h:outputText id="message" value="Hello #{myHelloBean.name} !" />

</h:body>

</html>

La seule contrainte pour que le composant puisse être mis à jour correctement c’est d’exister dans la page générée avant la demande de rechargement. Le code suivant ne fonctionnerai pas par exemple :

<h:outputText id="message" value="Hello #{myHelloBean.name} !"
              render="#{not emty myHelloBean.name}" />

Le déploiement

Pour déployer cette application, il suffit d’utiliser le plugin wildfly avec la commande suivante : mvn wildfly:run. Ensuite de se rendre sur l’adresse http://localhost:8080/hello-world-ajax/index.jsf  et de visualiser le résultat :

Après avoir saisi son nom et cliqué sur le bouton validé, seul le libellé “Hello !” est mis à jour :

Que s’est-il passé coté HTTP lorsque le bouton “valider” est pressé ? Une requête POST est envoyée à la servlet JSF qui donne la main au contrôleur. Ensuite pour le rechargement seul un rechargement partiel est envoyé à la page d’origine. On peut d’ailleurs voir le contenu du message mis à jour. Le flux qui transite sur le réseau est donc limité au strict minimum.

Ce tutoriel est disponible sur GitHub à l’adresse suivante : https://github.com/yanLanglois/jsf-2.2-tutoriel/tree/master/hello-world-ajax.

Bash – Transformer une chaîne de caractères en un entier

By , 15/03/2014

Pour transformer une chaîne de caractères numérique en un entier à l’aide de la ligne de commande unix (bash par exemple), il est possible d’utiliser l’opérateur “+” avec son identité soit le “0″.

Cas pratique, lorsqu’on a un programme qui code une adresse IPv4 avec systématiquement 3 digits pour chaque champ de l’adresse on peut éliminer les 0 non nécessaires en combinant cet astuce et la commande awk :

Dans cet exemple, le séparateur est le “.” et chaque partie de l’adresse IP est transformée en entier pour pouvoir supprimer les 0 en préfixes.

Pour plus d’information sur la commande awk : http://www.shellunix.com/awk.html.

JSF2.2 – Hello world

By , 14/03/2014

Voici un exemple d’une application JSF2.2 minimaliste. Une vue xhtml un bean Java contenant le message “Hello world !”. Une configuration minimaliste aussi pour pouvoir déployer l’application dans le serveur wildfly.

Vue d’ensemble et configurations

Pour cette application il est suffisant d’avoir un fichier Java porteur des données (le model), un fichier xhtml décrivant la vue et un quelques fichiers de configuration :

  • beans.xml : ce fichier est vide dans cet exemple. Il permet à l’application de bénéficier du CDI
  • faces-config.xml : ce fichier est vide dans cet exemple. Il permet de configurer tout ce qui est en lien avec JSF
  • web.xml : ce fichier est facultatif je l’ai ajouté pour avoir un exemple de namespace XML pour la bonne version du serveur wildfly

Pour rappel, JSF est une technologie qui se base sur le modèle MVC-2. Le rôle du contrôleur est joué par la servlet JSF qui centralise les demandes provenant de la vue et qui redirige vers les bons traitements Java (avec JSF on parle en général d’actions).

Le model (Bean Java)

L’objet Java qui va contenir les données, c’est à dire le message “Hello world !” est un String. Cet objet va être créé par un producer en scope Request. A chaque nouvel appel à la vue, une nouvelle requête sera nécessaire et l’objet sera recréé de toute pièce.

package org.eiw.data;

import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces;
import javax.inject.Named;

/***
 * Le producer est dans le scope Request,
 * il sera recréé à chaque nouvelle requête HTTP.
 */
@RequestScoped
public class HelloWorldProducer {
	private String message;

	/**
	 * La méthode qui produit l'objet de données vis à vis de la page XHTML.
	 */
	@Named
	@Produces
	public String getMessage() {
		return message;
	}

	/**
	 * La méthode qui initialise l'objet,
	 * à chaque nouvelle requête HTTP.
	 */
	@PostConstruct
	public void initMessage() {
		message = "Hello world !";
	}
}

La vue (XHTML)

Dans ce fichier, nous allons utiliser le conteneur CDI pour récupérer l’objet Java des données vu ci-dessus. Nous allons ensuite l’associer à un tag JSF pour formater son affichage :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
	<h:outputText value="#{message}" />
</h:body>

Pour récupérer l’objet, il faut utiliser son nom qui est égal par défaut au nom de l’instance avec le langage EL : #{maVariable}.

Le déploiement

Pour déployer cette application, il suffit d’utiliser le plugin wildfly avec la commande suivante : mvn wildfly:run. Ensuite de se rendre sur l’adresse http://localhost:8080/hello-world/index.jsf  et de visualiser le résultat :

Remarque : s’il s’agit de la première fois que vous utilisez le plugin wildfly, il vous faudra un peu de temps pour démarrer l’application car il est nécessaire de télécharger, dans le repository maven local, le serveur complet avant de le démarrer.

Ce tutoriel est disponible sur GitHub à l’adresse suivante : https://github.com/yanLanglois/jsf-2.2-tutoriel/tree/master/hello-world.

Maven – Wildfly plugin

By , 08/03/2014

J’ai découvert qu’il existait un plugin maven pour le serveur d’application Wildfly qui se comporte exactement comme le plugin maven pour tomcat. Pour l’utiliser, il faut ajouter ces quelques lignes dans le fichier pom.xml.

<project>
    ...
    <build>
        ...
        <plugins>
            ...
            <plugin>
                <groupId>org.wildfly.plugins</groupId>
                <artifactId>wildfly-maven-plugin</artifactId>
                <version>1.0.1.Final</version>
            </plugin>
            ...
        </plugins>
        ...
    </build>
...
</project>

Le goal wildfly:run compile et package le projet, puis le déploie dans une instance du serveur. Deux possibilités, soit la variable d’environnement wildfly.home existe et le serveur installé à cet emplacement est utilisé, soit elle n’existe pas et le serveur wildfly est téléchargé puis déployé dans le répertoire target du projet.

Le plugin permet beaucoup plus de choses que le simple démarrage de l’application dans un conteneur piloté par Maven. Pour plus d’information, son adresse est la suivante : https://docs.jboss.org/wildfly/plugins/maven/latest/.

7Zip : How to

By , 05/03/2014

Depuis plusieurs semaines, je trouve que nous ne savons pas assez bien profiter des utilitaires de compression de données. Mon impression s’est renforcée lorsque j’ai du découper un fichier en plusieurs petits fichiers ou volumes de même taille. C’est pourquoi aujourd’hui, je souhaite consacrer un peu de temps pour découvrir ou redécouvrir  l’utilitaire 7z connu sous le nom de 7-Zip.

Dans la suite de mes exemples, je vais me baser sur un fichier PDF de quelques Mo. Pour information, le contenu d’un fichier PDF est déjà compressé avec la méthode Deflate. La même qui est utilisée pour les fichiers Zip entre autre. C’est pourquoi la taille du fichier compressé sera identique à la taille du fichier non compressé.

Fonctions

Ce sont les paramètres de commande qui ne sont préfixés par un “-”. Les fonctions sont essentiellement la compression, la décompression et la visualisation du contenu de l’archive.

Compresser le fichier

Pour compresser le fichier monPdf.pdf en monPdf.7z, il faut utiliser la fonction “a” comme “ajout” ou “add”.

xx@xx $ 7z a monPdf.7z monPdf.pdf

Décompresser le fichier

Pour décompresser un fichier il faut utiliser soit la fonction “e” soit la fonction “x”. Avec “x” les chemins dans l’archive sont conservés lors de l’opération de décompression.

xx@xx $ 7z x monPdf.7z

Listing d’une archive

Pour visualiser le contenu d’une archive : les fichiers ainsi que des données statistiques, il faut utiliser la fonction “l” comme “liste” ou “list”.

xx@xx $ 7z l monPdf.7z

7-Zip [64] 9.20  Copyright (c) 1999-2010 Igor Pavlov  2010-11-18
p7zip Version 9.20 (locale=fr_FR.UTF-8,Utf16=on,HugeFiles=on,4 CPUs)

Listing archive: monPdf.7z

--
Path = monPdf.7z
Type = 7z
Method = LZMA
Solid = -
Blocks = 1
Physical Size = 4035385
Headers Size = 122

Date      Time    Attr         Size   Compressed  Name
------------------- ----- ------------ ------------  ------------------------
2014-03-05 20:36:40 ....A      3989103      4035263  monPdf.pdf
------------------- ----- ------------ ------------  ------------------------
3989103      4035263  1 files, 0 folders

Swithes

Compresser un fichier en plusieurs volumes

Pour cela il faut utiliser le swith “-v” comme “volume” avec la taille du volume.

xx@xx $ 7z a -v1M monPdf.7z monPdf.pdf
xx@xx $ ls -lh
... monPdf.7z.001
... monPdf.7z.002
... monPdf.7z.003

Cette commande va générer plusieurs petits fichiers 7z de 1Mo suffixés par le numéro du volume sur 3 chiffres. Les formats des unités possibles sont b (bytes), k (kilo bytes), m (mega bytes) et g (giga bytes). Pour décompresser une archive multi-volumes, il faut demander la décompression du premier volume : 001.

Entrée-sortie standard

Il est possible d’écrire le flux compressé ou décompressé sur la sortie (ou l’entrée) standard. Cela peut être utile pour faire des combinaisons de commandes comme, par exemple, avec le gestionnaire d’archive tar. Pour cela il faut utiliser les swithes “-si” et “-so” :

xx@xx $ tar cf - directory | 7z a -si directory.tar.7z
xx@xx $ 7z x -so directory.tar.7z | tar xf -

Protection via un mot de passe

Il est possible de protéger son archive grâce un mot de passe. Pour cela deux switches sont utilisés “-p” pour saisir le mot de passe et “-mhe=on|off” pour savoir s’il faut chiffrer les noms des fichiers de l’archive. Par défaut, ils ne sont pas chiffrés.

xx@xx $7z a -pModeDePasse monPdf.7z monPdf.pdf
xx@xx $7z a -pModeDePasse -mhe=on monPdf.7z monPdf.pdf

Il existe d’autres fonctions et switches pour 7-Zip. Je pense avoir fait le tour des plus utiles. Pour plus d’information, la documentation est très bien faite : http://linux.die.net/man/1/7z.

J2EE 6 : @Inject ou @EJB

By , 26/02/2014

Depuis J2EE5 et la spécification EJB (JSR-318), l’annotation @javax.ejb.EJB permet d’injecter une instance d’un EJB dans une variable.

Grâce à J2EE6 et la spécification Dependency Injection (JSR-330), l’annotation @javax.inject.Inject permet d’injecter n’importe quelle sorte de POJO (Plain Old Java Object) dont, bien entendu, des EJB dans une variable. Quelle annotation utiliser ?

Dans la plupart des cas, il est préférable d’utiliser l’annotation @javax.inject.Inject au lieu de @javax.ejb.EJB car elle est globale à toutes les sortes d’objets. Il faudra impérativement utiliser @javax.ejb.EJB lorsque :

  • Le conteneur où est déployée l’application n’est pas compatible avec CDI
  • L’EJB à injecter est un EJB remote

Comme indiqué dans la documentation de référence de Weld, si l’on souhaite utiliser l’annotation @javax.inject.Inject pour injecter un EJB remote, il est nécessaire de passer par un autre objet référenceant l’EJB remote via l’annotation @javax.ejb.EJB :

@Produces @EJB(ejbLink="../their.jar#PaymentService")
PaymentService paymentService;

Pour plus d’information, lire la documentation de Weld ou ce message intéressant sur le forum JBoss : https://community.jboss.org/thread/179388?start=15&tstart=0,

OfficeFolders theme by Themocracy