Posts tagged: Java

Arquillian – Graphene et RichFaces

By , 29/07/2014

Richfaces 4.5.0.Alpha3 est sortie ! Avec cette version, une nouveauté, les fragments de page (pages-fragments). Il s’agit de classes qui permettent de développer des tests unitaires automatisés sur les applications utilisant RichFaces.

La configuration Maven pour utiliser ces fragements est la suivante :

<dependency>
    <groupId>org.richfaces</groupId>
    <artifactId>richfaces-page-fragments</artifactId>
    <version>4.5.0.Alpha3</version>
    <scope>test</scope>
</dependency>

Les sources sont disponibles sur GitHub : https://github.com/richfaces/richfaces/tree/master/build/page-fragments.

Pour plus d’informations sur Arquillian : http://slides.com/vineetreynolds/the-arquillian-universe.

Pour plus d’informations sur les tests d’application JSF : http://www.bleathem.ca/talks/2012-JavaOne/testing-jsf.html.

JBoss – Tracer les requêtes HTTP

By , 22/07/2014

En travaillant sur un test Graphene 2, je me suis rendu compte qu’il pouvait être très intéressant de tracer le contenu des requêtes HTTP attaquant une application web. Lorsque cette application est déployée sur un serveur JBoss, il suffit d’ajouter une ligne dans le fichier jboss-web.xml :

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
   <valve>
      <class-name>org.apache.catalina.valves.RequestDumperValve</class-name>
   </valve>
</jboss-web>

Remarque, je n’ai pas essayé sur WildFly, mais la technique devrait fonctionner de la même façon. Ce fichier doit être dans le répertoire WEB-INF de l’archive web.

JSF2.2 – Inclure une librairie Javascript

By , 16/07/2014

Il existe un composant standard pour inclure une librairie Javascript : h:outputScript. Pour que JSF trouve cette librairie, il faut quelle soit présente dans un répertoire de type resources :

  • Soit à la racine du contexte web : src/main/webapp/resources pour un projet Maven
  • Soit directement encapsulée dans un jar : META-INF/resources

A mon sens, les deux attributs les plus importants de ce composant sont :

  • library : Le chemin du répertoire où se trouve le fichier Javascript en prenant en compte le répertoire resources comme référence
  • name : Le nom du fichier Javascript

Par exemple pour inclure le fichier Javascript se trouvant dans src/main/webapp/resources/ma/librairie/lib.js ou bien dans META-INF/resources/ma/librairie/lib.js :

<h:outputScript library="ma/librairie" name="lib.js" />

Pour tester sur des cas réels, vous pouvez récupérer une des nombreuses librairies Javascript packagées dans un jar disponibles à cette adresse : http://www.webjars.org/. Pour vous facilité la tâche ces librairies sont disponibles sur Maven. Par exemple pour ajouter aux dépendances de votre projet la librairie amchart :

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>amcharts</artifactId>
    <version>3.10.0</version>
</dependency>

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.

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.

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.

J2SE7 – multi catch – gérer plusieurs types d’exceptions

By , 21/02/2014

Jusqu’à présent, pour gérer plusieurs exceptions dans un bloc try/catch, il fallait un bloc catch par type d’exception. Il était bien entendu possible de “rattraper” une exception de haut niveau, de découvrir son type d’instance avec l’opérateur instance of puis de décider comment la traiter ou la relancer.

Désormais, il est aussi possible de déclarer plusieurs types d’exceptions dans un même bloc catch. Voici un exemple :

try {
   ...
} catch (IOException e) {
    System.out.println(e.getMessage());
} catch (MonException e) {
    System.out.println(e.getMessage());
} catch (Exception e) {
    System.err.println(e.getMessage());
}

// A partir de JavaSE 7
try {
   ...
} catch (IOException | MonException e) {
    System.out.println(e.getMessage());
} catch (Exception e) {
    System.err.println(e.getMessage());
}

J2SE7 – opérateur en diamant

By , 21/02/2014

Avec Java 7, beaucoup de nouveautés sont arrivées. L’opérateur en diamant, par exemple, permet d’éliminer une redondance dans la rédaction du code source lorsque l’on déclare une collection. Par exemple avant Java 7 il fallait déclarer sa collection ainsi :

List<MaClasse> maListe = new ArrayList<MaClasse>();

Maintenant, il n’est plus nécessaire de préciser le type de la collection dans la l’instanciation :

List<MaClasse> maListe = new ArrayList<>();

J2EE : Singletons

By , 08/02/2014

Développer soit-même un singleton, cela n’a plus aucun intérêt. Des annotations sont faites pour cela :

  • @javax.ejb.Singleton – Un nouveau type d’EJB provenant dans la JSR-318. Il est utilisé pour obtenir une seule instance partagée d’une même EJB. Cette instance est thread safe et transactionnelle.
  • @javax.inject.Singleton – Provient de la JSR-330, la classe annotée de cette manière ne sera instanciée qu’une seule fois.
  • @javax.enterprise.inject.ApplicationScoped – Un scope provenant de la JSR-299 (CDI), le bean est dans le scope application.
  • @javax.faces.bean.ApplicationScoped – Définie dans JSF 2.0 (JSR-314) Managed Beans, c’est un managed bean JSF qui est placé dans le scope application.

Toutes ces annotations vont nous permettre d’obtenir des singletons. Mais quelles sont les différences entre elles ?

La différence entre les deux annotations @javax.enterprise.inject.ApplicationScoped et @javax.faces.bean.ApplicationScoped c’est le contexte de déploiement. Si le conteneur utilisé est compatible CDI il faut utiliser l’annotation CDI  sinon, si le conteneur n’est pas compatible CDI (par exemple Tomcat) il faut utiliser l’annotation JSF2.0.

Quelles sont donc les différences entre les trois premières annotations ?

L’annotation EJB - @javax.ejb.Singleton – est la seule à proposer les services  “entreprise”, c’est à dire la gestion des transactions et de la concurrence. Il faut donc l’utiliser quand ces services “entreprise” sont nécessaires. Remarque, dans ce cas, il est tout à fait possible d’utiliser un EJB statefull avec un scope application - @javax.enterprise.inject.ApplicationScoped. Cet objet sera gérer de façon différente par le conteneur CDI mais il aura exactement les mêmes caractéristiques qu’un EJB @javax.ejb.Singleton. Donc, à mon avis, autant utiliser l’EJB singleton plutôt que le statefull en scope application.

Si vous n’avez pas besoin des services “entreprise”, autant utiliser un POJO normal, managed bean dans J2EE, avec le scope application. C’est à dire @javax.enterprise.inject.ApplicationScoped.

L’annotation @javax.inject.Singleton ne sera vraiment utile que dans un contexte J2SE. Pour plus d’information, il faut lire la documentation de référence de weld concernat le pseudo-scope Singleton.

PicketLink : Activer les traces dans le fichier de log

By , 30/01/2014

Pour débuger l’authentification faite grâce à picketLink avec JBoss Wildfly, il est nécessaire d’ajouter le logger ci-dessous puis de modifier la priorité par défaut de la console.

org.picketlink.idm

Pour cela, il faut se connecter à la console du serveur d’application puis se rendre sur la gestion des logger dans l’onglet “LOG CATEGORIES”.

Ajouter la catégorie associée au package picketLink avec le niveau DEBUG.

Enfin dans la catégorie “HANDLER”, modifier le niveau de log du handler console.

Pour information, les modifications sont prises en compte à chaud. Pas besoin de redémarrer le serveur.

OfficeFolders theme by Themocracy