Base de connaissances CCM
Programmation - Langages - Java




Sujet 6908 - Voir le contenu d'un fichier .jar

[ Voir ce sujet en ligne ] - [ Catégorie: Programmation - Langages - Java ]

Rien de plus facile que de voir ce que contient un fichier .jar: Renommez-le en .zip et ouvrez-le !

Si vous voulez voir ce que contiennent les programmes java compilés .class, vous devrez utiliser un décompilateur Java tel que JAD: www.kpdus.com
(Notez que certains fichiers .class sont protégé contre la décompilation par obfuscation fr.wikipedia.org du code.)

Lire la suite

Installation et utilisation du Plugin FindBugs d’Elipse »
Publié par sebsauvage - Dernière mise à jour le 18 novembre 2009 à 15:04 par marlalapocket




Sujet 19006 - Installation et utilisation du Plugin FindBugs d’Elipse

[ Voir ce sujet en ligne ] - [ Catégorie: Programmation - Langages - Java ]


FindBugs est un outil d'analyse statique qui examine les classes à la recherche d'éventuels problèmes au cours du développement, il s’agit donc d’un audit de code. Pour ce faire, il analyse le bytecode à la recherche de certains patterns connus. Il ne se limite pas à une recherche par expressions régulières, il essaye de comprendre ce que le programme veut faire.



Installation du plugin


Pré installation :


Simplement supprimer le répertoire de.tobject.findbugs_0.0.n qui se trouve sous le répertoire plugins du Eclipse.

Installation :


Afin d’installer le plugin FindBugs, suivre les étapes suivantes:







Puis cliquer sur OK.
Sélectionner le checkbox “FindBugs update site”, puis cliquer sur “Finish”.

Sélectionner le checkbox puis cliquer sur "next".



Utilisation du plugin


Fenêtre FindBugs






Visualisation des bugs



Les “bugs” détectés par findBugs apparaissent dans la fenêtre Bug Explorer.

Lire la suite

Hibernate [Partie 1]: Présentation »
Publié par n00r - Dernière mise à jour le 30 octobre 2009 à 14:51 par marlalapocket




Sujet 19368 - Hibernate [Partie 1]: Présentation

[ Voir ce sujet en ligne ] - [ Catégorie: Programmation - Langages - Java ]


Présentation de Hibernate








Hibernate est une couche résidant dans la JVM permettant d’assurer le mapping des objets JAVA cachés dans la JVM aux modèle relationnel ou modèle de données. Hibernate assure aussi le transfert des classes Java dans les entités de données et donc des données des objet dans les entités et les tables.
Hibernate présente aussi un language de manipulation des objets mappés connus sous le nom HQL. Il s’agit de faire des select, Update et Delete avec des opérations de somme, comtage (count), de calcul de moyenne,etc. HQL présente aussi des limites tel que l’utilisation des opérations d’Union.
Dans sa couche la plus proche de la base de données, Hibernate utilise JDBC (JDBC Template) pour dialoguer avec la base de données.
La Figure ci-dessous les constituants d’Hibernate utilisant une base de données et les composants de configuration pour fournir au développeur d’une application JAVA des objets persistance et assurer le transport de données entre ces objets et les tables de la base de données.


Plusieurs outils de mapping relationnel/objet Hibernate existent dans la communauté Hibernate. Un des plus connus Middlegen, l’objectif est d’assister le développeur pour définir de façon complète le mapping Hibernate.

La Session Hibernate :


Un loading d’objet mappé (de persistence) de la base de données ou la mise à jour (Update , insertion ou suppression) ne peut se faire que si une session Hibernate est instanciée. La session est une couche représentée par l’interface JAVA org.hibernate.Session
Pour un développeur d’une application JAVA, toute l’activité Hibernate commence après l’instruction
session = sessionFactory.openSession ()

sessionFactory est un objet créé par l’application et qui utilise la connexion JDBC (ou JNDI).
L’activité Hibernate finisse après l’appel de la méthode
session.close () 

Entre ces deux méthodes citées dessus , une transaction peut être lancée en appelant
session.beginTransaction().

Distribution et principales classes et interfaces :


La version 3 de Hibernate est téléchargeable à partir du lien
Les principaux jars sont les suivants :

La classe org.hibernate.cfg.Configuration
Le constructeur de Configuration utilise le fichier de configuration de Hibernate (hibernate.cfg.xml.)
La classe
 org.hibernate.HibernateException

Pratiquement toutes les méthodes Hibernate peuvent déclencher cette exception.
Interface org.hibernate.SessionFactory
C’est la première instance créé en appelant :
new org.hibernate.cfg.Configuration ().configure ().buildSessionFactory ();


Il permet de lire les fichiers hbm (voir partie configuration).
Interface org.hibernate.Session
Interface org.hibernate.Query
Interface qui permet à un développeur d’écrire des requêtes Hibernate (HQL) en utilisant les objets JAVA de persistence.
Interface org.hibernate.SQLQuery
Interface qui permet à un développeur d’écrire des requêtes SQL.
Interface org.hibernate.Transaction
Il s’agit de l’objet transaction Hibernate avec comme principales fonction de commit() et de rollback().

Voir aussi: Hibernate (Partie 2): configuration et utilisation

Lire la suite

Hibernate [Partie 2]: configuration et utilisation »
Publié par n00r - Dernière mise à jour le 30 octobre 2009 à 14:54 par marlalapocket




Sujet 19371 - Hibernate [Partie 2]: configuration et utilisation

[ Voir ce sujet en ligne ] - [ Catégorie: Programmation - Langages - Java ]


Voir la première partie de l'astuce Hibernate (Partie 1): Présentation



configuration et utilisation de Hibernate


Configuration Hibernate dans une application JAVA


Ce fichier est recommandé d’être placé sur le répertoire contenant le code source (source JAVA) de l’application JAVA.

Ci-dessous un exemple de fichier hibernate.cfg.xml avec les commentaires nécessaires :

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration
    PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
    "[http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

  <session-factory>
	
    	 
				
		<property name="hibernate.connection.url">jdbc:oracle:thin:@dbServer:1521:db</property> 
		<property name="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</property>
        	<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
		<property name="hibernate.connection.username">dbusername</property>
		<property name="hibernate.connection.password">dbpassword</property>
		
 			
		<!-- Configuration hibernate -->
       		 <property name="show_sql">true</property>
		<property name="format_sql">true</property>  
       		 <property name="hibernate.use_outer_join">true</property>
		<property name="hibernate.query.substitutions">1</property>
		<property name="hibernate.connection.autocommit">false</property>
		<property name="hibernate.jdbc.batch_size">50</property>
		<property name="hibernate.jdbc.use_get_generated_keys">true</property>

		
		<!-- Pool de connexion : ici C3P0 qui est déclaré -->
		<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
		<property name="hibernate.c3p0.acquire_increment">3</property> 
		<property name="hibernate.c3p0.idle_test_period">180</property> 
		<property name="hibernate.c3p0.max_size">100</property> 
		<property name="hibernate.c3p0.min_size">10</property> 
		<property name="hibernate.c3p0.timeout">1000</property>
		
		 <!—désactiver la cache  deuxième niveau -->
		<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

				
		
		
		<!—Liste des fichiers de Mapping hbm -->
		<mapping resource="com/org/client/mapping/Client.hbm.xml"/>
		
		
	</session-factory>
  </hibernate-configuration>



*
C’est un ensemble de fichiers qui fait le mapping entre l’entité de base de données et l’objet JAVA de persistence associé.
Les chemins complets de tous les fichiers de mapping hbm sont décrits dans le fichier de configuration hibernate.cfg.xml. (voir exemple du fichier de configuration ci-dessus)

Utilisation de Hibernate dans une application JAVA :


Dans l’exemple d’utilisation nous allons nous reposer sur l'exemple du fichier de configuration Hibernate ci-dessus

CREATE TABLE CLIENT
(
	  ID_Client NUMBER(10) NOT NULL,
	  TITRE VARCHAR2(10),
	  NOM VARCHAR2(30),	  
	  REMISE NUMBER(19,5),
	  CA NUMBER(19,5),
	  CONSTRAINT PK_CLIENT PRIMARY KEY (CLIENT_ID)
);

/** constructeur par défaut */

public Client() {
}

/** Constructeur complet **/
public Client(Long clientId, String titre, String nom, BigDecimal remise, BigDecimal ca)
{
this.idClient = idClient;
this.titre = titre;
this.name = name;
this.remise = remise;
this.ca = ca;
}

/** Les getters et setters**/
public Long getIdClient()
{
return this.clientId;
}
public void setIdClient (Long clientId) {
this.clientId = clientId;
}
public String getTitre() {
return this.titre;
}
public void setTitre(String titre) {
this.titre = titre;
}
public String getNom() {
return this.nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public BigDecimal getRemise() {
return this.remise;
}
public void setRemise(BigDecimal remise) {
this.remise = remise;
}
public BigDecimal getCa() {
return this.ca;
}
public void setCa(BigDecimal ca) {
this.ca = ca;
}
}

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
    
<hibernate-mapping>
<class 
    name="[Nom_Package].Client" 
    table="CLIENT"
         entity-name="Client"
>	
    <meta attribute="class-description" inherit="false">
       @hibernate.class
        table="CLIENT"
    </meta>

    <id
        name="idClient"
        type="java.lang.Long"
        column="ID_CLIENT"
    >
		    <meta attribute="field-description" inherit="false">
		       Id du client
		    </meta>
    
        <meta attribute="field-description">
           @hibernate.id
            generator-class="assigned"
            type="java.lang.Long"
            column="CLIENT_ID"

        </meta>
        <generator class="increment" />
    </id>

    <property
        name="titre"
        type="java.lang.String"
        column="TITRE"
        length="10"
    >
		    <meta attribute="field-description" inherit="false">
		       Titre du client
		    </meta>
        <meta attribute="field-description">
           @hibernate.property
            column="TITRE"
            length="10"
        </meta>    
    </property>
    <property
        name="name"
        type="java.lang.String"
        column="NAME"
        length="30"
    >
		    <meta attribute="field-description" inherit="false">
		       Nom du client
		    </meta>
        <meta attribute="field-description">
           @hibernate.property
            column="NAME"
            length="30"
        </meta>    
    </property>

    <property
        name="remise"
        type="java.math.BigDecimal"
        column="REMISE"
        length="19"
    >
		    <meta attribute="field-description" inherit="false">
		       Remise du client
		    </meta>
        <meta attribute="field-description">
           @hibernate.property
            column="REMISE"
            length="19"
        </meta>    
    </property>
    <property
        name="ca"
        type="java.math.BigDecimal"
        column="CA"
        length="19"
    >
		    <meta attribute="field-description" inherit="false">
		       Chiffre Affaire
		    </meta>


</class>
</hibernate-mapping>

La clé primaire est définie dans la balise <id> : dans l’exemple, elle est basée sur une séquence. Il est possible de définir une clé composée en utilisant la balise <composite-id> :
	<composite-id>
      	<key-property name="attribut1"/>
     	 	<key-property name="attribut2"/>
	</composite-id>


L’exemple ci-dessous utilise la méthode saveOrUpdate() de la session hibernate.
org.hibernate.Session sess = sessFact.openSession();
Client c = new Client();
c.setName("John");
p.setTitre("Mr");
Transaction tx = sess.beginTransaction();
sess.saveOrUpdate(p);
tx.commit();
sess.close();

Lire la suite

Taglibs [Partie 1]: Présentation »
Publié par n00r - Dernière mise à jour le 30 octobre 2009 à 14:53 par marlalapocket




Sujet 19383 - Taglibs [Partie 1]: Présentation

[ Voir ce sujet en ligne ] - [ Catégorie: Programmation - Langages - Java ]




Présentation des TagLibs


Les Tag Librairies ou JSP Tag Libraries sont des librairies développées pour être intégrées et utilisées dans les pages JSP d’une application J2EE.
Une Taglib à utiliser exécute un ensemble d'actions destinées à être utilisée dans une page JSP sous forme de tags ou balises XML. Ces actions manipulent des données et des variables de la page JSP et de l’application JAVA J2EE.
Une TagLib est définie par un descripteur de taglib ou Tag Librarie Descriptor et de classes Java qui implémentent l'interface Jsp Tag.
Ce descripteur est bien représenté par est un fichier XML d’extension tld décrivant les liens entre les balises et les classes Java. Une balise XML écrite dans la page JSP fait appels à ces actions. Ces balises sont remplacé seulement pendant la compilation de la JSP sur le serveur d’application par un appel des classes JAVA correspondante.
Ci-dessous un exemple de balises standard préfixées avec jsp :

<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles"%>
<%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%>


Une taglib permet donc d’optimiser le code JAVA à écrire dans une page JSP.
Une Taglib est représentée par trois composants :

Frameworks se basant sur les Taglibs


Dans le but faire une optimisation de code JAVA des application JAVA J2EE, plusieurs frameworks utilisent tels que Struts, SpringMVC, JSTL.

JSTL, développé par SUN, propose une librairie standard pour la plupart des fonctionnalités de base d'une application JAVA J2EE, et la plupart des taglibs présents actuellement étendent la librairie JSTL. C’est pour cette raison que JSTL est utilisé comme framework de base afin d'utiliser l'api native de Sun.

Différentes Versions des Taglib


Il existe actuellement trois versions des taglibs.
A une version de Taglib, correspond une version de J2EE une version JSP :



La version 2.0 est récente. qui n'est pas encore supportée par les éditeurs.
La version 1.2 moins récente, est plus utilisée des sur le marché.
Ces deux versions sont supportées par JAVA 1.5.


Voir aussi: Taglibs (Partie 2): Mise en place d’un TagLib

Lire la suite

Taglibs [Partie 2]: Mise en place d’un TagLib »
Publié par n00r - Dernière mise à jour le 30 octobre 2009 à 14:48 par marlalapocket




Sujet 19384 - Taglibs [Partie 2]: Mise en place d’un TagLib

[ Voir ce sujet en ligne ] - [ Catégorie: Programmation - Langages - Java ]


Voir la première partie de l'astuce Taglibs (Partie 1): Présentation

Taglibs [Partie 2]: Mise en place d’un TagLib


Un fichier XML qui est le descripteur de Taglib est obligatioire pour utiliser une TagLib. Ce fichier définie les balises (tags) de la librairie. Ci-dessous un exemple :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<taglib>
	<tlib-version>1.0</tlib-version>
	<jsp-version>1.2</jsp-version>
	 <short-name>montagamoi</short-name>

<uri>http://www.owliance.com/taglibs/montagamoi-1.0</uri>
	<description>Bibliothèque de taglibs</description>	
<tag>
		<name>switchtag</name>
		<tag-class>monpackage.SwitchTag</tag-class>
		<description>Tag qui affiche le corps ...</description>
		<attribute>
			<name>test</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
	</tag>
	<tag>
		<name>casetag</name>
		<tag-class>monpackage.CaseTag</tag-class>
		<description>Tag qui affiche le corps ...</description>
		<attribute>
			<name>value</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
	</tag>
	<tag>
		<name>iteratetag</name>
		<tag-class>monpackage.IterateTag</tag-class>
		<description>Tag qui affiche le corps ...</description>
		<attribute>
			<name>count</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
			<type>java.lang.Integer</type>
		</attribute>
	</tag>
</taglib>


Dans ce fichier exemple, nous trouvons trois tags :

Les informations de la première partie du fichier tld sont :

En ce qui concerne les balises qui composent la librairie :
Le Tag « attribute » contient les balises suivantes :


*

Dans la page JSP qui utilise la Taglib:
<%@ taglib uri="http://www.owliance.com/taglibs/montagamoi-1.0" prefix="montagamoi"%>

<br/>
<br/>
<montagamoi:iteratetag count="10">
<br/>
<montagamoi:switchtag test="3">
<montagamoi:casetag value="0">Zéro</montagamoi:casetag>
<montagamoi:casetag value="1">Un</montagamoi:casetag>
<montagamoi:casetag value="2">Deux</montagamoi:casetag>
<montagamoi:casetag value="3">Trois</montagamoi:casetag>
</montagamoi:switchtag>
</montagamoi:iteratetag>


Ci-dessous le contenu de la classe IterateTag.java

package monpackage;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;

public class IterateTag extends BodyTagSupport {
	/**

	 * 
	 */
	private static final long serialVersionUID = 9368853820192946960L;
	private int count = 0;
	private int current;


	public void setCount(int i) {
		count = i;
	}

	public int doStartTag() throws JspException {
		current = 0;
		if (current < count) {
			return EVAL_BODY_INCLUDE;
		} else {
			return SKIP_BODY;
		}
	}

	public int doAfterBody() throws JspException {
		current++;
		if (current < count) {
			return EVAL_BODY_AGAIN;
		} else {
			return SKIP_BODY;
		}
	}
}


Ci-dessous le contenu de la classe CaseTag

package monpackage;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

public class CaseTag extends TagSupport {
	public String value;

	public void setValue(String p_value) {
		this.value = p_value;
	}

	public int doStartTag() throws JspException {
		if (this.getParent() instanceof SwitchTag) {
			SwitchTag parent = (SwitchTag) getParent();
			if (parent.isValid(this.value))
				return EVAL_BODY_INCLUDE;
			else
				return SKIP_BODY;
		} else {
			throw new JspException(
					"Le Tag case doit être à l'intérieur du tag Switch");
		}

	}
}


Ci-dessous le contenu de la classe SwitchTag

package monpackage;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

public class SwitchTag extends TagSupport {
	/**

	 * 
	 */
	private static final long serialVersionUID = 3752830055610590228L;
	private String test;

	public int doStartTag() throws JspException {
		return EVAL_BODY_INCLUDE;
	}

	public void setTest(String p_value) {
		test = p_value;
	}

	public boolean isValid(String caseValue) {
		if (test == null)
			return false;
		return (test.equals(caseValue));
	}
}



*

Lire la suite

Framework de test StrutsTestCase (Partie 2): Ecriture des Tests »
Publié par n00r - Dernière mise à jour le 30 octobre 2009 à 14:49 par marlalapocket




Sujet 19389 - Framework de test StrutsTestCase (Partie 2): Ecriture des Tests

[ Voir ce sujet en ligne ] - [ Catégorie: Programmation - Langages - Java ]

Voir la première partie de l'astuce Framework de test StrutsTestCase (Partie 1): Présentation



Ecriture des Tests utilisant le Framework de test StrutsTestCase et configuration


1.Ecriture des tests


Le framework StrutsTestCase offre une panoplie de méthodes de validation se basant sur le framework Junit. Ses méthodes servent à écrire un scénario de test moyennant des instructions de bases. Ses méthodes sont décrites dans le tableau ci-après.


Pour mieux expliquer comment procéder pour tester une action struts nous allons traiter un cas pratique simple mais qui illustre bien l’utilisation de StrutsTestCase.

Considérons la classe LoginAction suivante qui permet de vérifier l’authentification d’un user. Dans cette classe on reçoit un ActionForm contenant les informations du login. Premièrement on essaye de récupérer le username et le password et d’assurer que ces informations sont valides. Si il y a une erreur au niveau des valeurs du username ou password on crée un ActionError dans lequel on spécifie le key du message. Et on essaye de faire un forward vers l’écran de login une autre fois. Dans l’autre cas où les informations du login sont valides on stocke ses informations dans la session. Ensuite on essaye de faire un forward vers l’écran suivant.
public class LoginAction extends Action {

	
	public ActionForward perform(ActionMapping mapping,
			ActionForm form,
			HttpServletRequest request,
			HttpServletResponse response)
	{
		
		String username = ((LoginForm)form).getUsername();
		String password = ((LoginForm)form).getPassword();
		ActionErrors errors = new ActionErrors();
		if ((!username.equals("dery")) || (!password.equals("radar")))
		{
			errors.add("password","error.password.mismatch");
		}
		
		if (!errors.empty())
		{
			saveErrors(request,errors);
			return mapping.findForward("login");
			
		}
		
		//sauvegarde du nom utilisateur dans la session
		HttpSession session = request.getSession();
		session.setAttribute("authentification", username);
		
		//forward vers URI success
		return mapping.findForward("success");

	}

}


Scénario de test

Dans cette classe, on peut tester :
StrutsTestCase permet de tester toutes ces conditions moyennant le framework Junit comme indiqué ci-dessous.
	public class TestLoginAction extends CactusStrutsTestCase 
	
	{

		public void setUp() {super.setUp();}
	
		public void tearDown() {super.tearDown();}
	
		public TestLoginAction (String testName) 
		{
			super(testName);
		}
	
		public void testSucessfullLogin(){}		
	}

public class TestLoginAction extends CactusStrutsTestCase {

	
	
	public TestLoginAction (String testName) 
	{
		super(testName);
	}
	
	public void testSucessfullLogin()
	{
		setRequestPathInfo("/login") ;
	}		

}

public class TestLoginAction extends CactusStrutsTestCase {

	
	
	public TestLoginAction (String testName) 
	{
		super(testName);
	}
	
	public void testSucessfullLogin()
	{
		setRequestPathInfo("/login") ;
		addRequestParameter("username", "dery");
		addRequestParameter("password", "radar");
	}		

}

public class TestLoginAction extends CactusStrutsTestCase {

	
	
	public TestLoginAction (String testName) 
	{
		super(testName);
	}
	
	public void testSucessfullLogin()
	{
		setRequestPathInfo("/login") ;
		addRequestParameter("username", "dery");
		addRequestParameter("password", "radar");
		actionPerform();
	}		

}

public class TestLoginAction extends CactusStrutsTestCase {

	
	
	public TestLoginAction (String testName) 
	{
		super(testName);
	}
	
	public void testSucessfullLogin()
	{
		setRequestPathInfo("/login") ;
		addRequestParameter("username", "dery");
		addRequestParameter("password", "radar");
		actionPerform();
		verifyForward("success");
	}		

}

public class TestLoginAction extends CactusStrutsTestCase {

	
	
	public TestLoginAction (String testName) 
	{
		super(testName);
	}
	
	public void testSucessfullLogin()
	{
		setRequestPathInfo("/login") ;
		addRequestParameter("username", "dery");
		addRequestParameter("password", "radar");
		actionPerform();
		verifyForward("success");
		assertEquals("dery", (String) getSession().getAttribute("authentification"));
	}
}

public class TestLoginAction extends CactusStrutsTestCase {

	
	
	public TestLoginAction (String testName) 
	{
		super(testName);
	}
	
	public void testSucessfullLogin()
	{
		setRequestPathInfo("/login") ;
		addRequestParameter("username", "dery");
		addRequestParameter("password", "radar");
		actionPerform();
		verifyForward("success");
		assertEquals("dery", (String)	getSession().getAttribute("authentification"));
		verifyNoActionErrors();
	}		

}

public void testFailedLogin()
{
	
		setRequestPathInfo("/login");
		addRequestParameter("username", "dery");
		addRequestParameter("password", "error");
		actionPerform();
		verifyForward("login");
		verifyActionErrors(new String[] {"error.password.mismatch"});
		assertNull((String)getSession().getAttribute("authentification"));
}

2.Best Practises lors de l’écriture des classes de tests cactus


Les développeurs des tests cactus doivent faire attention aux règles suivantes :

3.Configuration du Cactus


Fichier cactus.properties :
Le fichier cactus.properties contient les paramètres nécessaires à l’exécution des scripts ANT utilisés pour le lancement des tests.
La propriété cactus.servletRedirectorName désigne le nom du servlet de redirection cactus qui doit obligatoirement être défini dans le fichier web.xml, comme suit :
<servlet>
<servlet-name>StrutsServletRedirector</servlet-name>
<servlet-class>
org.apache.cactus.server.ServletTestRedirector
</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>StrutsServletRedirector</servlet-name>
<url-pattern>/StrutsServletRedirector</url-pattern>
</servlet-mapping>

Lire la suite

Framework de test StrutsTestCase (Partie 1): Présentation »
Publié par n00r - Dernière mise à jour le 7 septembre 2009 à 16:52 par n00r




Sujet 19390 - Framework de test StrutsTestCase (Partie 1): Présentation

[ Voir ce sujet en ligne ] - [ Catégorie: Programmation - Langages - Java ]




Présentation du Framework de test StrutsTestCase


Présentation générale


Le framework de test StrutsTestCase, des applications JAVA JEE est une extention du framework de test standard Junit. L’héritage de la classe TestCase permet de fournir des facilités pour tester du code basé sur le framework Struts. StrutsTestCase est basé sur deux approches différentes pour tester le code Struts en exécutant l’ActionServlet soit dans un environnement réel avec un moteur de servlet standard soit dans un environnement de simulation. C’est deux approches sont :

Comme StrutsTestCase utilise le contrôleur ActionServlet pour tester le code, il est possible de tester non seulement l’implémentation des objets « Action » mais aussi le mapping, les formBeans, les déclarations de forward, les paths associés au forward et les messages d’erreur retournés par les actions. Par ailleurs, StrutsTestCase fourni déjà des méthodes de validation (assertEquals, assertNotNull,…) permettant de faire des tests unitaires plus approfondis, rapides et faciles.

StrutsTestCase est hébergé dans le site SourceForge sur le lien. La toute dernière version 2.1.4 peut être téléchargée à partir du lien download sur cette page. StrutsTestCase est compatible avec les spécifications Java Servlet 2.2, 2.3 et 2.4. Il supporte struts 1.2 et 1.3. Ainsi, il est compatible avec les framework Cactus1.7 et Junit 3.8.1.

Les différentes approches de test


Comme mentionné plus haut, les deux approches les plus répondues pour tester les classes coté serveur sont :

StrutsTestCase permet de permuter d’une approche à l’autre avec un impact minimal sur les classes de test. En effet, le setup de StrutsTestCase et les méthodes de validation sont exactement les même pour les deux approches. Ainsi, modifier l’approche revient juste à modifier la classe de base à partir de laquelle hérite la classe de test.
StrutsTestCase fourni deux classes de base qui étendent, toutes les, le standard TestCase de JUnit. Ces deux classes sont :

Liste des jars du framework StrutsTestCase


Le frameWork StrutsTestCase est composé par les bibliothèques suivantes :


Voir aussi: Ecriture des Tests utilisant le Framework de test StrutsTestCase et configuration

Lire la suite

Axis 2 [Partie 1] »
Publié par n00r - Dernière mise à jour le 30 octobre 2009 à 14:47 par marlalapocket




Sujet 19453 - Axis 2 - Partie 1

[ Voir ce sujet en ligne ] - [ Catégorie: Programmation - Langages - Java ]

« PrécédentSuivant »
Sommaire

Axis 2

Concept


Le concept des Web Service tourne autour des trois acronymes suivants :
Axis est un engin permettant la création et le déploiment des web services, réalisé par Apache Software Foundation. C'est un package Java libre qui fournit :
Axis 2.0 est une réécriture complète qui a pour objectif d'être plus efficace, plus modulaire et plus orienté XML que la version précédente. Un certain nombre de modules sont en cours de développement concernant la sécurité, les transactions...

Fonctionnement : runtime


La structure de l'échange entre le web service et l'application cliente peut être représentée comme suit :

Axis2 : WSDL2Java


Axis permet la conversion d'un fichier WSDL en un ensemble de classes Java

Axis2 : Databinding framework ADB


Conversion la plus simple de XML en objet : pour cela Il existe de modes

Distribution Axis


Sur le site d'apache on trouve une distribution binaire standard de Axis qui contient tous les jars nécessaires à l'exécution et la compilation de Axis ainsi que des scripts permettant un déploiement facile de l'application : http://ws.apache.org/axis2/
Publié par n00r - Dernière mise à jour le 23 juin 2011 à 17:01 par @ntoine
Ce document intitulé « Axis 2 - Partie 1 » issu de CommentCaMarche.net (CCM) (www.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.




Sujet 19469 - Configuration du Framework Acegi dans application Web JAVA J2EE

[ Voir ce sujet en ligne ] - [ Catégorie: Programmation - Langages - Java ]



Etapes de configuration du Framework Acegi dans une application Web JAVA J2EE


La configuration passe par cinq étapes :

Etape 1: Mettre le acegi-security-1.0.0-RC2.jar sous le répertoire lib de votre application:



Etape 2: Configuration des listeners et des filtres:


Etape 3: Configuration des filtres et des listeners dans le fichier web.xml:


Tout d'abord, nous devons mettre en place la logique de filtres d'ACEGI. Pour cela, il faut mettre à jour le fichier web.xml de notre application Web en y définissant un filtre au sens servlet. Ce filtre va charger sa propre configuration depuis les fichiers de configuration Spring.</code>
<filter>
		<filter-name>localeFilter</filter-name>
		<filter-class>com.cleyris.ebee.filter.LocaleFilter</filter-class>
	</filter>
…..
  <listener>
        <listener-class>com.cleyris.ebee.listener.StartupListener</listener-class>
    </listener>
    <listener>
        <listener-class>com.cleyris.ebee.listener.UserCounterListener</listener-class>
    </listener>

Etape 4: Configuration des filtres au niveau du fichier de configuration de Spring:


Ce fichier doit de trouver sous /WEB-INF/
Dans notre application, ce fichier est nommé applicationContext-security.xml
Dans notre fichier de configuration Spring, nous allons maintenant déclarer les filtres ACEGI chargés de mettre en oeuvre notre stratégie de sécurisation. Pour faire propre, il faudrait créer plusieurs fichiers de configuration.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
       default-lazy-init="true">

    <!-- ======================== FILTER CHAIN ======================= -->
    <bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
        <property name="filterInvocationDefinitionSource">
            <value>
                CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
                PATTERN_TYPE_APACHE_ANT
                /**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
            </value>
            <!-- Put channelProcessingFilter before securityContextHolderAwareRequestFilter to turn on SSL switching -->
            <!-- It's off by default b/c Canoo WebTest doesn't support SSL out-of-the-box -->
        </property>
    </bean>
    <!-- Pour limiter le nombre des connecteurs à la session en même temps -->
	<bean id="concurrentSessionController"
		class="org.acegisecurity.concurrent.ConcurrentSessionControllerImpl">
		<property name="maximumSessions">
			<value>1</value>
		</property>
		<property name="sessionRegistry">
			<ref local="sessionRegistry" />
		</property>
	</bean>
	<bean id="sessionRegistry"
		class="org.acegisecurity.concurrent.SessionRegistryImpl" />
    <bean id="httpSessionContextIntegrationFilter" class="org.acegisecurity.context.HttpSessionContextIntegrationFilter"/>
	<!-- Fin -->
    <!-- Changed to use logout.jsp since causes 404 on WebSphere: http://issues.appfuse.org/browse/APF-566 -->
    <bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
        <constructor-arg value="/index.jsp"/>
        <constructor-arg>
            <list>
                <ref bean="rememberMeServices"/>
                <bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
            </list>
        </constructor-arg>
        <property name="filterProcessesUrl" value="/logout.jsp"/>
    </bean>

    <bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="authenticationFailureUrl" value="/login.jsp?error=true"/>
        <property name="defaultTargetUrl" value="/"/>
        <property name="filterProcessesUrl" value="/j_security_check"/>
        <property name="rememberMeServices" ref="rememberMeServices"/>
    </bean>

    <bean id="securityContextHolderAwareRequestFilter" class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter"/>

    <bean id="rememberMeProcessingFilter" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="rememberMeServices" ref="rememberMeServices"/>
    </bean>

    <bean id="anonymousProcessingFilter" class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter">
        <property name="key" value="anonymous"/>
        <property name="userAttribute" value="anonymous,ROLE_ANONYMOUS"/>
    </bean>

    <bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
        <property name="authenticationEntryPoint">
            <bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
                <property name="loginFormUrl" value="/login.jsp"/>
                <property name="forceHttps" value="false"/>
            </bean>
        </property>
    </bean>

    <bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="accessDecisionManager" ref="accessDecisionManager"/>
        <property name="objectDefinitionSource">
            <value>
                PATTERN_TYPE_APACHE_ANT
                /passwordHint.html*=ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER
                /signup.html*=ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER
                /a4j.res/*.html*=ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER <!-- APF-737, OK to remove if not using JSF -->
                /**/*.html*=ROLE_ADMIN,ROLE_USER
            </value>
        </property>
    </bean>

    <bean id="accessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">
        <property name="allowIfAllAbstainDecisions" value="false"/>
        <property name="decisionVoters">
            <list>
                <bean class="org.acegisecurity.vote.RoleVoter"/>
            </list>
        </property>
    </bean>

    <bean id="rememberMeServices" class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
        <property name="userDetailsService" ref="UserDao"/>
        <property name="key" value="23_*!cdU='612./e;NrI"/>
        <property name="parameter" value="rememberMe"/>
    </bean>

    <bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
        <property name="providers">
            <list>
                <ref local="daoAuthenticationProvider"/>
                <ref local="anonymousAuthenticationProvider"/>
                <ref local="rememberMeAuthenticationProvider"/>
            </list>
        </property>
    </bean>

    <bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
         <property name="userDetailsService" ref="UserDao"/>
         <property name="passwordEncoder" ref="passwordEncoder"/>
    </bean>

    <bean id="anonymousAuthenticationProvider" class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
        <property name="key" value="anonymous"/>
    </bean>

    <bean id="rememberMeAuthenticationProvider" class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
        <property name="key" value="23_*!cdU='612./e;NrI"/>
    </bean>

    <!-- This bean definition must be available to ApplicationContext.getBean() so StartupListener
         can look for it and detect if password encryption is turned on or not -->
    <bean id="passwordEncoder" class="org.acegisecurity.providers.encoding.ShaPasswordEncoder"/>

    <!-- This bean is optional; it isn't used by any other bean as it only listens and logs -->
    <bean id="loggerListener" class="org.acegisecurity.event.authentication.LoggerListener"/>

    <!-- Apply method-level interceptor to userManager bean -->
    <aop:config>
        <aop:advisor id="managerSecurity" advice-ref="methodSecurityInterceptor" pointcut="execution(* com.cleyris.ebee.core.service.UserManager.*(..))"/>
    </aop:config>

    <bean id="methodSecurityInterceptor" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="accessDecisionManager" ref="accessDecisionManager"/>
        <property name="objectDefinitionSource">
             <value>
                 com.cleyris.ebee.core.service.UserManager.getUsers=ROLE_ADMIN
                 com.cleyris.ebee.core.service.UserManager.removeUser=ROLE_ADMIN
             </value>
        </property>
    </bean>

    <!-- SSL Switching: to use this, configure it in the filterChainProxy bean -->
    <bean id="channelProcessingFilter" class="org.acegisecurity.securechannel.ChannelProcessingFilter">
        <property name="channelDecisionManager" ref="channelDecisionManager"/>
        <property name="filterInvocationDefinitionSource">
            <value>
                PATTERN_TYPE_APACHE_ANT
                /admin/**=REQUIRES_SECURE_CHANNEL
                /login*=REQUIRES_SECURE_CHANNEL
                /j_security_check*=REQUIRES_SECURE_CHANNEL
                /signup.html*=REQUIRES_SECURE_CHANNEL
                /saveUser.html*=REQUIRES_SECURE_CHANNEL
                /**=REQUIRES_INSECURE_CHANNEL
            </value>
        </property>
    </bean>

    <bean id="channelDecisionManager" class="org.acegisecurity.securechannel.ChannelDecisionManagerImpl">
        <property name="channelProcessors">
            <list>
                <bean class="org.acegisecurity.securechannel.SecureChannelProcessor"/>
                <bean class="org.acegisecurity.securechannel.InsecureChannelProcessor"/>
            </list>
        </property>
    </bean>
</beans>

Au niveau de ce fichier, nous avons défini les pages d’index, de login et de logout, le nombre maximal d’ouverture de session, les différents rôles…

Etape 5: Création de l’interface UserManager, de son implémentation, de userDao et de la classe POJO User:


public interface UserManager extends Manager {
	……
	/**

	 * 
	 * @param user cette methode est utilis�e par acegi pour ajouter un autre utilisateur 
	 * @return
	 * @throws UserExistsException
	 */
	public User saveUser(User user) throws UserExistsException;
	
	/**

	 * cette methode est utilis�e par acegi pour intercepter un utilisateur
	 * @param userId
	 * @return
	 */
	public User getUser(String userId);
	
	/**

	 * cette methode est utilis�e par acegi pour supprimer un utilisateur
	 * @param userId
	 */
	public void removeUser(String userId);
	
	/**

	 * 
	 * @param username cette methode est utilis�e par acegi pour afficher l'utilisateur � travers son login
	 * @return
	 * @throws UsernameNotFoundException
	 */
	public User getUserByUsername(String username) throws UsernameNotFoundException, CleyrisException ;
……………
}

public class UserManagerImpl extends BaseManager implements UserManager{

	//c'est la partie Acegi
	
    @SuppressWarnings("unchecked")
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        List<UserDetails> users = userDAO.setHqlQuery("from User where username=:username").setParameter("username",username).list();
        if (users == null || users.isEmpty()) {
            throw new UsernameNotFoundException("user '" + username + "' not found...");
        } else {
            return (UserDetails) users.get(0);
        }
    }
    
    public User getUser(String userId) {
        return userDao.get(new Long(userId));
    }
    
    public User saveUser(User user) throws UserExistsException {
        // if new user, lowercase userId
        if (user.getUserId()== 0) {
            user.setUsername(user.getUsername().toLowerCase());
        }

        try {
            return userDao.saveUser(user);
        } catch (DataIntegrityViolationException e) {
           
            if (log.isErrorEnabled())
				log
						.error("Exception occurs class:com.cleyris.ebee.core.service.UserManagerImpl.java  method:saveUser: "
								+ e.getMessage() + ".");
            throw new UserExistsException(Constants.UserExists);
        } catch (EntityExistsException e) { // needed for JPA
           
            if (log.isErrorEnabled())
				log
						.error("Exception occurs class:com.cleyris.ebee.core.service.UserManagerImpl.java  method:saveUser: "
								+ e.getMessage() + ".");
            throw new UserExistsException(Constants.UserExists);
        }
    }

    public void removeUser(String userId) {
        log.debug("removing user: " + userId);
        userDao.remove(new Long(userId));
    }
    
      public User getUserByUsername(String username) throws UsernameNotFoundException, CleyrisException {
    	User user= (User) userDao.loadUserByUsername(username);
        return user;
    }
    public List<User> getUsers(User user) {
        return userDao.getUsers();
    }
}

package com.cleyris.ebee.core.dao;

import java.util.List;

import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.springframework.transaction.annotation.Transactional;

import com.cleyris.ebee.core.modele.User;

/**

 * @author mlaouini
 */
public interface UserDao extends BaseDao<User, Long> {

    /**

     * charger les informations d'utilisateurs basé sur login .
     * @param username the user's username
     * @return userDetails populated userDetails object
     * @throws org.acegisecurity.userdetails.UsernameNotFoundException thrown when user not found in database
     */
    @Transactional
    UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;

    /**

     * charger une liste d'utilisateurs trier par le login en appliquant le majuscule sur le login ==>username.
     *

     * @return List populated list of users
     */
    List<User> getUsers();

    /**

     * sauvegarder un utilisateur.
     * @param user the object to be saved
     * @return the persisted User object
     */
    User saveUser(User user);
}

public class UserDaoImpl extends BaseDaoImpl<User, Long> implements UserDao, UserDetailsService {

    public UserDaoImpl() {
        super(User.class);
    }

    /**

     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    public List<User> getUsers() {
        return getHibernateTemplate().find("from User u order by upper(u.username)");
    }

    /**

     * {@inheritDoc}
     */
    public User saveUser(User user) {
        log.debug("user's id: " + user.getUserId());
        getHibernateTemplate().saveOrUpdate(user);
        // necessary to throw a DataIntegrityViolation and catch it in UserManager
        getHibernateTemplate().flush();
        return user;
    }

    public User save(User user) {
        return this.saveUser(user);
    }

    /** 

     * {@inheritDoc}
    */
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        List users = getHibernateTemplate().find("from User where username=?", username);
        if (users == null || users.isEmpty()) {
            throw new UsernameNotFoundException("user '" + username + "' not found...");
        } else {
            return (UserDetails) users.get(0);
        }
    }
}

/**

 * @author mlaouini
 */
@Entity
@javax.persistence.SequenceGenerator(name="SEQ_STORE",sequenceName="sequence_users")
@Table(name = "users", schema = "ebee")
public class User extends BaseObject implements UserDetails {

	…………
	private String username; // required
	private String password; // required
	private String confirmPassword;
	private String passwordHint;
	private Set<Role> roles = new HashSet<Role>();
	private boolean enabled;
	private boolean accountExpired;
	private boolean accountLocked;
	private boolean credentialsExpired;

…………………
	@ManyToMany(fetch = FetchType.EAGER)
	@JoinTable(name = "user_role", schema = "ebee", joinColumns = { @JoinColumn(name = "userid", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "roleid", nullable = false, updatable = false) })
	@NotNull
	public Set<Role> getRoles() {
		return this.roles;
	}

	public void setRoles(Set<Role> roles) {
		this.roles = roles;
	}

	
	/**

	 * @see org.acegisecurity.userdetails.UserDetails#getAuthorities()
	 * @return GrantedAuthority[] an array of roles.
	 */
	@Transient
	public GrantedAuthority[] getAuthorities() {
		return roles.toArray(new GrantedAuthority[0]);
	}

	@Column(name = "account_enabled")
	public boolean isEnabled() {
		return enabled;
	}

	@Column(name = "account_expired", nullable = false)
	public boolean isAccountExpired() {
		return accountExpired;
	}

	/**

	 * @see org.acegisecurity.userdetails.UserDetails#isAccountNonExpired()
	 */
	@Transient
	public boolean isAccountNonExpired() {
		return !isAccountExpired();
	}

	@Column(name = "account_locked", nullable = false)
	public boolean isAccountLocked() {
		return accountLocked;
	}

	/**

	 * @see org.acegisecurity.userdetails.UserDetails#isAccountNonLocked()
	 */
	@Transient
	public boolean isAccountNonLocked() {
		return !isAccountLocked();
	}

	@Column(name = "credentials_expired", nullable = false)
	public boolean isCredentialsExpired() {
		return credentialsExpired;
	}

	/**

	 * @see org.acegisecurity.userdetails.UserDetails#isCredentialsNonExpired()
	 */
	@Transient
	public boolean isCredentialsNonExpired() {
		return !credentialsExpired;
	}

	@Column(nullable = false, length = 50, unique = true)
	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	@Column(nullable = false)
	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	@Transient
	public String getConfirmPassword() {
		return confirmPassword;
	}

	public void setConfirmPassword(String confirmPassword) {
		this.confirmPassword = confirmPassword;
	}

	@Column(name = "password_hint")
	public String getPasswordHint() {
		return passwordHint;
	}

	public void setPasswordHint(String passwordHint) {
		this.passwordHint = passwordHint;
	}

	
	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}

	public void setAccountExpired(boolean accountExpired) {
		this.accountExpired = accountExpired;
	}

	public void setAccountLocked(boolean accountLocked) {
		this.accountLocked = accountLocked;
	}

	public void setCredentialsExpired(boolean credentialsExpired) {
		this.credentialsExpired = credentialsExpired;
	}
	
}

La classe User.java implémente UserDetails. Cette interface fournit des informations de base sur l'utilisateur. Les implémentations ne sont pas directement utilisées par Acegi pour des raisons de sécurité. Elles stockent tout simplement des informations sur l'utilisateur qui sont ensuite encapsulées dans des objets d'authentification.

Lire la suite

Axis 2 [Partie 2]: Mise en place et utilisation »
Publié par n00r - Dernière mise à jour le 9 septembre 2009 à 16:12 par n00r




Sujet 19479 - Axis 2 [Partie 2]: Mise en place et utilisation

[ Voir ce sujet en ligne ] - [ Catégorie: Programmation - Langages - Java ]



Axis 2: Mise en place et utilisation


Mise en place


axis2-web 
META-INF
WEB-INF
    classes 
    conf
        axis2.xml 
    lib
        activation.jar
        ...
        xmlSchema.jar
    modules
        modules.list 
        addressing.mar
        ...
        soapmonitor.mar
    services
        services.list
        aservice.aar
        ...
        version.aar
    web.xml







Déploiement des Web Service


Les web service Axis2 peuvent être déployés sous forme de fichier *.aar. Un service a donc une structure bien déterminée comme indiqué ci-après
- CataloguePrix
   - META-INF
     - services.xml
   - lib
   - com
     - owliance
       - console
         - parametrage
           - CataloguePrix.class

Où CataloguePrix est le nom du service qui doit être le même que celui indiqué dans le fichier services.xml. Les classes sont mises directement à la racine avec leurs packages. Et le répertoire lib contient les *.jar nécessaire pour l’exécution des services. Le fichier services.xml défini le service et lui fait correspondre la classe java adéquate.



Création du web service

Le prototype de projet suivant montre bien comment créer un web service. Il s’agit d’un projet eclipse avec l’arborescence suivante :





Lire la suite

Concept de l’Intégration Continue »
Publié par n00r - Dernière mise à jour le 10 septembre 2009 à 15:24 par n00r




Sujet 24318 - Concept de l’Intégration Continue

[ Voir ce sujet en ligne ] - [ Catégorie: Programmation - Langages - Java ]



Introduction


Le processus d’intégration continue a pour objectif principal de vérifier que chaque mise à jour du code source ne génère pas de régressions et/ou d’anomalies sur une application en cours de développement.
Historiquement, l’intégration continue a été utilisée par IBM pour le développement de l’OS/360 depuis les années 60.
L’intégration continue n’est pas un outil mais plutôt une pratique issue de l'eXtreme Programming (XP).
Les développeurs d’une même application réintègrent le programme sur lequel ils travaillent le plus fréquemment possible. Il s’agit de déclencher à chaque intégration un processus qui se base sur une platforme qui vérifié automatiquement le fonctionnement de l’application afin que les anomalies soient détectées à leur entrée.

Le plus difficile pour un développeur est de réfléchir sur l’impact réel d’une mise à jour fondamentale sur l’ensemble des fonctionnalités de l’application. L’intégration continue permet de, donner au développeur cette vision plus générale sur l’application puisque les tests de l’application se font sur un environnement clone de production.

Mots clés


Scénario général


Fonctionnalités générales d’un serveur d’intégration continue


Un serveur d’intégration continue doit principalement permettre :

Les serveurs de d’intégration les plus connus

Lire la suite

Serveurs d’intégration CruiseControl Vs Hudson »
Publié par wjaouadi - Dernière mise à jour le 1 décembre 2009 à 18:03 par wjaouadi




Sujet 24319 - Serveurs d’intégration CruiseControl Vs Hudson

[ Voir ce sujet en ligne ] - [ Catégorie: Programmation - Langages - Java ]

Le but de cet faq partie est d’établir une comparaison entre les deux serveurs d’intégration CruiseControl et Husdon.

Rappel sur les principales fonctionnalités d’un serveur d’intégration


Principalement les serveurs d’intégration permettent de :

Le processus de build automatisé et récursif permet de

Comparaison Hudson/CruiseControl


Conclusion


En conclusion les deux serveurs d’intégration permettent pratiquement les mêmes fonctionnalités avec un léger avantage pour CruiseControl compte tenu de la richesse de ses IHM de reporting, de son évolutivité et surtout la richesse de la documentation. Par ailleurs migrer d’un serveur à l’autre n’est pas vraiment une tâche difficile ou coûteuse. Ainsi CruiseControl est choisi comme serveur d’intégration pour l’environnement de développement intégré cible. Et si Hudson prend l’avantage dans le future il est simple de migre vers ce serveur.

Lire la suite

Installation et configuration de Cruise Control »
Publié par wjaouadi - Dernière mise à jour le 1 décembre 2009 à 18:03 par wjaouadi




Sujet 24460 - Installation et configuration de Cruise Control

[ Voir ce sujet en ligne ] - [ Catégorie: Programmation - Langages - Java ]

L’intégration qui permet de révéler les éventuelles erreurs et incompatibilités des différentes parties réalisées par chaque développeur de l’équipe.
Cruise Control, étant un serveur d’intégration continue, permet d’automatiser cette phase d’intégration selon la succession des tâches suivantes :

Nous allons donc commencer par une explication de ce qu'est l'intégration continue, puis nous expliquons comment configurer CruiseControle.

Intégration continue


L'intégration continue est une technique de développement/management de projet qui implique d'intégrer très fréquemment le travail de tous les membres d'une équipe. Ensuite, une compilation automatique doit être lancée pour vérifier les éventuelles erreurs de compilation du projet puis si possible les tests unitaires doivent aussi être lancés.
Concrètement, l'intégration continue est le fait d'automatiser des compilations fréquentes du code source d'une équipe incluant les derniers changements de tous ses membres. La plupart des outils d'intégration continue sont capable de faire les actions suivantes :

En réalité, la plupart des serveurs d'intégration continue se basant sur ANT ou MAVEN (ou les deux), ils permettent une liste quasi infinie d'actions possibles.
Les bénéfices d'une intégration continue sont indéniables, elle permet de vérifier petit à petit le travail de toute l'équipe, de détecter les erreurs beaucoup plus rapidement et d'assurer la cohérence de l'application. Couplé à un lancement des tests, elle permet de voir l'évolution de la qualité de l'application et montre les progrès de l'équipe en temps réel. Le plus souvent, ces outils sont livrés avec des modules de statistique très intéressants.
Bien sur, utiliser un serveur d'intégration continue implique de se donner quelques règles de développements sans lesquels l'intérêt d'une intégration continue est amoindri:
Pour aller plus loin, l'excellent article de Martin Flower(en anglais): http://www.martinfowler.com/articles/continuousIntegration.html

Installation


Il vous faudra tout d’abord télécharger Cruise Control à l’adresse suivante : http://cruisecontrol.sourceforge.net/download.html
A noter qu’il faut vérifier l’existence de la variable d’environnement JAVA_HOME qui pointe sur le répertoire du JDK.
Ensuite, lancez Cruise control (via le menu Programme ou via le fichier .bat installé) et tout fonctionne. Cruise control est fournit avec une application d'exemple, il lance par défaut une application de reporting ‘Cruise Config’, un dashboard, un serveur JMX, et tout ça accessible via un simple browser.

Cruise Config


Lancez tout d'abord l'application de configuration de Cruise Control (Cruise Config) qui est une application Java Webstart, ce qui est fort pratique car vous pouvez alors la lancer depuis un ordinateur différent de votre serveur d'intégration.
Une fois l’application lancée, vous devriez voir un panneau vide.



Entrez les informations suivantes sur le serveur que vous souhaitez surveiller.


Une fois vous avez mis en place un ou plusieurs serveurs, appuyez sur le bouton OK pour terminer la configuration du serveur. La demande fera apparaître un onglet pour chacun avec l'état actuel des projets en eux.

Lire la suite

FrameWork TestNG : principe et installation dans WSAD »
Publié par wjaouadi - Dernière mise à jour le 1 décembre 2009 à 18:02 par wjaouadi




Sujet 24461 - FrameWork TestNG : principe et installation dans WSAD

[ Voir ce sujet en ligne ] - [ Catégorie: Programmation - Langages - Java ]

TestNG (Test Next Generation) est un outil de tests unitaires Java semblable dans son approche à JUnit. Il apporte cependant des améliorations qui le font préférer à JUnit. En effet il offre la possibilité aux développeurs d’utiliser une amélioration importante de Java 5, à savoir les annotations.
C’est par ailleurs un framework très simple à mettre en œuvre et à intégrer dans des projets, il assure une rétro-compatibilité avec les tests JUnit et il propose d’ailleurs un plugin permettant de l’interfacer dans l’environnement de développement Eclipse. D’autre part il offre une flexibilité d’écriture, une organisation très ouverte des tests et des fonctionnalités très avancées comme la généralisation des tests.

Fonctionnalités


TestNG offre des différentes fonctionnalités qui sont :

Comparaison avec JUnit



Intégration dans WSAD


Pour l'intégration de TestNG au niveau de WSAD, il faut :

Lire la suite

FrameWork TestNG : Exemple d’utilisation sur WSAD »
Publié par wjaouadi - Dernière mise à jour le 1 décembre 2009 à 18:02 par wjaouadi




Sujet 24462 - FrameWork TestNG : Exemple d’utilisation sur WSAD

[ Voir ce sujet en ligne ] - [ Catégorie: Programmation - Langages - Java ]

Nous allons utiliser TestNG pour vérifier le fonctionnement de la couche Service, DAO, JPA et Hibernate, pour faire ça nous avons écris cette classe de test :
package odas.toolbox.testng.test;

import java.text.ParseException;
import java.util.List;

import odas.toolbox.persistance.jpa.hibernate.model.P70paramet;
import odas.toolbox.persistance.service.IService;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;



public class TestNG {
//	 couche service
	private IService service;

	@BeforeClass
	public void init() {
		// log
		log("init");
		// configuration de l'application
		ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");
		// couche service
		service = (IService) ctx.getBean("service");
	}

	@BeforeMethod
	public void setUp() throws ParseException {
		// on vide la base
		clean();
		// on la remplit
		fill();
	}

	// logs
	private void log(String message) {
		System.out.println("----------- " + message);
	}

	// affichage contenu table
	private void dump() {
		log("dump");
		System.out.format("[personnes]%n");
		for (P70paramet p : service.getAll()) {
			System.out.println(p);
		}
	}

	// remplissage table
	public void fill() throws ParseException {
		log("fill");
		// création personnes
		P70paramet p1 = new P70paramet();
		P70paramet p2 = new P70paramet();
		// qu'on sauvegarde
		service.saveArray(new P70paramet[] { p1, p2 });
	}
	// supression éléments de la table
	public void clean() {
		log("clean");
		for (P70paramet p : service.getAll()) {
			service.delete(p.getP70idpkpar());
		}
	}
	@Test()
	public void test01() {
		log("test1");
		//dump();
		// liste des personnes
		List<P70paramet> parametres = service.getAll();
		assert 119 == parametres.size();
	}
}

L’annotation @BeforeClass désigne la méthode à exécuter pour initialiser la configuration nécessaire aux tests. Elle est exécutée avant que le premier test ne soit exécuté. L'annotation @AfterClass non utilisée ici, désigne la méthode à exécuter une fois que tous les tests ont été exécutés.

La méthode init annotée par @BeforeClass exploite le fichier de configuration de Spring pour instancier les différentes couches de l'application et avoir une référence sur la couche [service]. Tous les tests utilisent ensuite cette référence.

L'annotation @BeforeMethod désigne la méthode à exécuter avant chaque test. L'annotation @AfterMethod, non utilisée ici, désigne la méthode à exécuter après chaque test.

La méthode setUp annotée par @BeforeMethod vide la base de données

L'annotation @Test désigne une méthode de test à exécuter.
Publié par wjaouadi - Dernière mise à jour le 1 décembre 2009 à 18:02 par wjaouadi





© Tous droits réservés 2010 Jean-François Pillou