Posts tagged: J2EE

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 – 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.

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,

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.

J2EE 6 : Doublons dans les scopes @…Scoped

By , 06/02/2014

Dans J2EE6 il existe deux spécifications qui parlent de scopes applicatifs : JSR 314: JavaServer Faces 2.0 et JSR 299: Contexts and Dependency Injection for the JavaTM EE platform (CDI). La difficulté vient du fait que ces scopes ont le même nom et la même fonction :

  • @javax.faces.bean.RequestScoped (JSF) et @javax.enterprise.context.RequestScoped (CDI).
  • @javax.faces.bean.SessionScoped (JSF) et @javax.enterprise.context.SessionScoped (CDI).
  • @javax.faces.bean.ApplicationScoped (JSF) et @javax.enterprise.context.ApplicationScoped (CDI).

Lesquels utilisés ? Comme pour certaines autres annotations qui semblent dupliquées dans J2EE, ces annotations sont identiques, elle diffèrent uniquement suivant le contexte de déploiement. JSF2.0 propose ses propres annotations pour laisser la possibilité aux développeurs de déployer des applications JSF2.0 dans des conteneurs dépourvus de CDI (Tomcat par exemple) mais en conservant l’avantage de l’outjection proposée par la JSR CDI.

Sachant cela, la sélection de ces annotations doit se faire en fonction du contexte de déploiement. Il faut bien entendu préférer les annotations CDI à JSF si le conteneur est compatible avec la JSR-299.

Il existe cependant un scope proposé par JSF2.0 et inexistant dans CDI : @ViewScoped. Il est possible dans ce cas d’utiliser la librairie DeltaSpike JSF ou Seam 3 Face Module pour avoir accès à une version CDI du scope.

JRebel Wildfly8.0.0.CR1

By , 05/02/2014

D’après le forum de zeroturnaround, JRebel 5.5.0 n’est pas compatible avec Wildfly8.0.0.CR1. Pour le rendre compatible il faut récupérer la dernière version de développement de JRebel (nigthly build) sur leur site internet : http://zeroturnaround.com/software/jrebel/download/early-access/.

Pour mettre à jour la librairie utilisée par le plugin JRebel dans eclipse , il faut se rendre dans l’écran de configuration JRebel : Help -> JRebel Config Center. Ensuite saisir le chemin de la librairie dans l’onglet Overview. Sinon, par défaut, le plugin utilise la version embarquée de la librairie.

@Model versus @Named versus @ManagedBean

By , 04/02/2014

Lorsque l’on débute en J2EE il est parfois difficile de voir la différence entre certaines annotations. Elles proviennent souvent de spécifications (JSR) différentes et peuvent avoir un rôle similaire ou totalement identique. Certaines fois, il s’agit uniquement d’une différence de contexte dans lequel le code est développé ou déployé.

Les annotations suivantes sont utiles pour déclarer des objets Java qui vont être accessibles dans le langage EL via les symboles #{} (on parle d’outjection par opposition à injection).

@javax.faces.bean.ManagedBean

Cette annotation arrive avec la JSR-314 JavaServer Faces 2.0. Grâce à elle, il n’est plus nécessaire de déclarer les Managed Bean JSF dans le fichier XML faces-config.xml. Elle n’est utile que lorsque le l’application développée est déployée dans un contexte où le conteneur CDI n’existe pas, comme Tomcat par example.

De plus, elle peut facilement être confondue avec l’annotation suivante @java.annotation.ManagedBean.

@javax.annotation.ManagedBean

Cette annotation est définie dans la JSR-250. Elle est utilisée pour déclarer un managed bean spécifié dans la JSR-316. Il ne faut pas confondre avec les managed bean JSF. Le principe de la JSR-316 est de pouvoir transformer n’importe quel POJO (Plain Old Java Object) en objet pouvoir avoir un cycle de vie, des intercepteurs, etc.

Dans un contexte CDI, cette annotation est obsolète car le principe du CDI est de transformer tous les POJO en Managed Bean. Donc cette annotation n’est pas du tout utile. Elle n’aura d’ailleurs aucun impact visible sur l’exécution du code.

@javax.enterprise.inject.Model @javax.inject.Named

L’annotation @Model est équivalante à l’annotation @Named à laquel il a été rajouté le contexte @RequestScoped (@javax.enterprise.context.RequestScoped).

Ces annotations proviennent de la JSR 299 “contexts and dependency injection” (CDI). Cette JSR offre beaucoup plus de possibilités d’utilisation que celle sur JSF2.0. Dans un contexte où une application est déployée dans un conteneur compatible CDI il est donc préférable d’utiliser les annotations CDI plutôt que JSF2.0.

Conclusion

Le choix de l’annotation à utiliser dépend essentiellement du conteneur où l’application sera déployée. Il est toujours préférable d’utiliser les annotations provenant de la JSR-299 (CDI) dans le cas où le conteneur est compatible avec CDI.

Pour plus d’information cet article est très intéressant : Is @javax.faces.bean.ManagedBean Dead on Arrival?

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.

Java EE 7 : Fichiers de déploiements (deployment descriptors)

By , 24/01/2014

Il est toujours compliqué de savoir quelles versions il faut utiliser pour les fichiers de description des déploiements (comme le fichier web.xml par exemple). Cet article a pour but de référencer les principaux fichiers utilisés dans le cadre d’une application java J2EE 7 avec une petite explication sur leur utilité.

CDI 1.1

Il s’agit du fichier beans.xml. Il est obligatoire si l’on souhaite utiliser l’injection de dépendance. Attention, il peut resté totalement vide.

<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       version="1.1" bean-discovery-mode="all">
</beans>

Ce fichier doit être déposé dans le répertoire WEB-INF/lib ou WEB-INF/classes/META-INF pour un archive web (WAR) et META-INF/ dans une archive java (JAR)

Pour plus d’information : JSR 346: Contexts and Dependency Injection for JavaTM EE 1.1

Bean Validation 1.1

Deux fichiers pour cette JSR (349) : validation.xml et constraints.xml

<validation-config
        xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration validation-configuration-1.1.xsd"
        version="1.1">
</validation-config>
<constraint-mappings
        xmlns="http://jboss.org/xml/ns/javax/validation/mapping"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.1.xsd"
        version="1.1">
</constraint-mappings>

Ces fichiers doivent être déposés dans le répertoire META-INF d’une archive Java (JAR).

Pour plus d’information : JSR 349: Bean Validation 1.1

JPA 2.1

Pour avoir accès à la base de données, il est obligatoire de posséder le fichier persistence.xml.

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
             version="2.1">
</persistence>

Il existe aussi un fichier de mapping des entités qui n’est pas obligatoire : orm.xml. Il permet, entre autre, de référencer des classes qui se trouvent dans une même application mais dans des librairies tierces (JAR).

<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm http://xmlns.jcp.org/xml/ns/persistence/orm_2_1.xsd"
                 version="2.1">
</entity-mappings>

Ces deux fichiers doivent être positionnés dans le répertoire META-INF/ dans une archive java (JAR). Pour rappel, seul le fichier persistence.xml est obligatoire s’il est question d’avoir des accès avec une base de données.

Pour plus d’information : JSR 338: JavaTM Persistence 2.1 :

EJB 3.2

Ce fichier n’est pas non plus obligatoire : ejb-jar.xml.

<ejb-jar xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/ejb-jar_3_2.xsd"
         version="3.2">
</ejb-jar>

Ce fichier doit être positionné dans le répertoire META-INF/ dans une archive java (JAR).

Pour plus d’information : JSR 345: Enterprise JavaBeansTM 3.2

Servlet 3.1

Pour plus d’information : JSR 340: Java Servlet 3.1 Specification

JSF 2.2

Pour la partie vue de J2EE7, le fichier faces-config.xml n’est plus obligatoire.

<faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
              version="2.2">
</faces-config>

Un fichier JSF est un fichier XML avec l’extention *.xhtml. Il se présente sous cette forme :

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
</html>

Le fichier faces-config.xml doit se trouver dans le répertoire WEB-INF/ d’une archive web (WAR).

Pour plus d’information : JSR 344: JavaServerTM Faces 2.2

JAX-WS 2.2

Pour les services web, il s’agit du fichier webservices.xml :

<webservices xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/javaee_web_services_1_4.xsd"
             version="1.4">
</webservices>

Il doit être positionné dans le répertoire WEB-INF/ d’une archive web (WAR).

Pour plus d’information : JSR 224: JavaTM API for XML-Based Web Services (JAX-WS) 2.0, JSR 109: Implementing Enterprise Web Services, JSR 181: Web Services Metadata for the JavaTM 

Conclusion

Pour plus d’information et connaître les autres fichiers qui permettre de réaliser d’autres types de traitements, par exemple des batchs en J2EE7 ou décrire une archives entreprises (EAR) : http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/javaee/index.html#7

Cet article est fortement inspiré de ce site internet : http://antoniogoncalves.org/2013/06/04/java-ee-7-deployment-descriptors/

JBoss 7 : Plusieurs instances standalone sur un même serveur

By , 13/06/2013

Pour démarrer une instance JBoss en mode standalone avec les configurations par défaut, il faut exécuter la commande suivante : $JBOSS_HOME/bin/standalone.sh

Pour créer sa propre instance, il est uniquement nécessaire de copier les fichiers de configuration originaux du serveur standalone dans un répertoire quelconque du système de fichier puis d’exécuter la commande précédente avec l’option -Djboss.server.base.dir=XX. Par exemple :

xxxx@xxxx:~/tmp/testsJboss1$ tree
.
├── configuration
│   ├── application-roles.properties
│   ├── application-users.properties
│   ├── logging.properties
│   ├── mgmt-users.properties
│   └── standalone.xml
└── deployments
xxxx@xxxx:~/$ $JBOSS_HOME/bin/standalone.sh -Djboss.server.base.dir=~/tmp/testsJboss1/

Remarque : L’option jboss.socket.binding.port-offset associée à un entier (-Djboss.socket.binding.port-offset=1), vous permet de démarrer une instance en décalant tous les ports du serveur et ainsi éviter toute interférence avec un autre serveur.

OfficeFolders theme by Themocracy