Вы находитесь на странице: 1из 111

Java EE

Java Enterprise Edition

Ce document a t contient des parties adaptes de support de cours de P.Y. Gibello, T. Dandelot et C. Dumoulin Le contenu de ce site est mis disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mmes Conditions 3.0 France.

Introduction JEE
Historique Architecture - Offre

Historique Java
nb classes JSE http://docs.oracle.com/javase/6/docs/api/
4500 4000 3500 3000 2500 2000 1500 1000 500 0 1.2 1.3 1.4.2 Java 5 Java 6 Java 7

nb classes JEE http://docs.oracle.com/javaee/6/api/


2000 1500 1000 500 0 J2EE J2EE 1.3 J2EE 1.4 Java EE 5 Java EE 6 1.2.1

Java EE - Objectifs
Faciliter le dveloppement de nouvelles applications java base de composants Intgration avec les systmes dinformation existants Support pour les applications critiques de lentreprise
haute disponibilit, tolrance aux pannes, monte en charge, scurit etc.

Architecture
Dcompose le systme concevoir en
o applications, en composants applicatifs, o analyse descendante jusquaux modules, aux classes gestionnaires, aux fonctions ou mthodes
Modules ou Objets gestionnaire, pour larchitecture logicielle o Reprsente les fonctions du systme o Implmente les fonctions et sous-fonctions des cas dutilisation o Services (ou fonctions) de gestion de donnes
CRUD (Create, Read, Update, Delete) sur les donnes mtier Services de recherche sur les donnes mtier Transactions / Paiements Calculs

o services mtiers

Architectures informatiques
Architectures pour une solution projet :
o Architectures logiques
applicative, mtier

o Architectures techniques
logicielle, systme, rseau, matrielle.
6

Architecture logique 4 /ers


IHM (ou GUI) : client
T1

Frontal (ou front-end) : prsenta/on Dorsal (ou back-end) : m/er Persistence : base de donnes

T2+T3
T2

T3

T4

Mutualiser le code m/er


T1 T1+T2

T2 Site Web

T2 Frontal API

T3

T4

Java EE Cest quoi?


http://java.sun.com/javaee Spcifications Modle de programmation Implmentation de rfrence
J2EE 1.0 1.4 en 2003, etc...

Standard en volution depuis 1997 Au dpart, applications Web n-tiers


Prsentation (Servlets puis JSP), essentiellement HTTP Logique mtier : EJB Donnes : JDBC

Puis infrastructure de support standard pour EAI

Facteurs de rationalisation majeurs (JTA, JMS, JCA, Web Services) Evolution de progiciels existants vers Java EE

Architecture 4 tiers JEE


Browser WEB Container

T2
JDBC JMS JTA

html

T1

HTTP

Servlets JSPs

jdbc

T4

T1+T2
Applets java/ash

RMI / IIOP Appel local JVM SOAP, REST RMI / IIOP


EJBs

JCA JAAS
JavaMail

DB
xxxx T4
EIS

T3

T1+T2
public static void

JNDI EJB Container

main() { Java Application

Java EE Application Server

Commerciale

Ore

Oracle (ex BEA) WebLogic IBM Websphere (n1) JBoss (n1 en nombre de dploiements) Oracle (ex Sun) Glassfish (Platform edition) OW2 JOnAS Apache Geronimo (Community edition de IBM Websphere) openEjb

Open Source

Open Source conteneur web uniquement :


Tomcat Jetty

Conteneur Web couche de prsentation


Servlet - WAR JSP taglib

Conteneur Web 1/2


Webapp web.xml html html html Servlet jsp Servlet Servlet webapp Servlet Servlet jpg css jar js html

Conteneur Web 2/2


Contient des applications Web dans un rpertoire Une application web est une arborescence de fichier
o o o o mywebapp/WEB-INF/web.xml mywebapp/WEB-INF/classes/*.class mywebapp/WEB-INF/lib/*.jar mywebapp/**/*.*

Un fichier .war est une archive zip de cette arborescence

Application Web
Servlets
Code java excut sur le serveur pour retourner une page HTML Gnration de contenu Web dynamique

JSP: Java Server Pages


o Mlange de HTML/XML et de code java o Librairies dextensions (taglibs) o Pr-compilation en servlet

Programme java appelable depuis une URL Classe qui hrite de javax.servlet.http.HttpServlet Cycle de vie de HttpServlet
o init() : 1er appel o service() : chaque appel, redirection vers doGet() ou doPost() o destroy() : arrt du serveur WEB

Servlet

Appel dune servlet


URL GET : http://myserver/mywapp/HelloWorld : doGet() <form method="post" target=""> : doPost(),

import java.io.*; import javax.servlet.*; import javax.servlet.http.*;

Exemple de servlet

public class HelloWorld extends HttpServlet { public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html><body>"); out.println("<h1>hello word !</h1>"); out.println("</body></html>"); } }

Ecrire une Servlet


Classe qui hrite de la javax.servlet.Servlet Surcharger la mthode dinitialisation init(), o Utiliser la mthode getInitParameter() Surcharger une mthode de gestion dappel o doPost(), doGet(), doPut(), doDelete(), doOptions() Analyser la requte, o Classe HttpServletRequest getParameter(), getCookie(), getSession() Utiliser la classe HttpServletResponse pour rpondre getWriter(), setContentType(), setCookie()

formulaire et Servlet
Champs des formulaires directement dans des variables :
<FORM ACTION="testServlet" METHOD="POST"> Votre nom : <INPUT TYPE=TEXT NAME="nom"> Votre ge : <INPUT TYPE=TEXT NAME="age"> <INPUT TYPE=SUBMIT VALUE="Ok"> </FORM>

Dans TestServlet.doGet(), lobjet request contient les saisies: o request.getParameter("nom") o request.getParameter("age") public void doGet( HttpServletRequest request, HttpServletResponse response) ... { out.println("Bonjour " + request.getParameter("nom"));
19

Dployer une servlet


Recopier lapplication web sous $tomcat/webapps
o une archive .war ou o Un rpertoire

Contenu de lapplication web


o sous-rpertoire WEB-INF/ web.xml : dclaration et paramtres de servlets /lib/ : pour les .jar, /classes/ pour les .class

Dclaration de la servlet
apache-tomcat-7.0.30/webapps/myapp/WEB-INF/web.xml <web-app> <servlet> <servlet-name>servletHello</servlet-name> <servlet-class>HelloWorld</servlet-class> </servlet> hYp://localhost:8080/myapp/hello <servlet-mapping> <servlet-name>servletHello</servlet-name> <url-paYern>/hello</url-paYern> </servlet-mapping> </web-app>

Autour des Servlets


Gestion de la session : HttpServletRequest.getSession() o donnes de contexte dure de vie courte o stockes sur le serveur o addAttribute(), getAttribute(), setMaxInactiveInterval() Gestion des cookies : HttpServletRequest.getCookies() o donnes de contexte dure de vie plus longue o stockes sur le poste client o setName(), setValue(), setMaxAge() Filtre o Transforme des requtes et/ou des rponses o Classe qui implmente javax.servlet .Filter o Dclar dans web.xml comme une Servlet

JSP
Java Server Pages
Intgration de code serveur dans un fichier HTML
o mmes principes que PHP o Code java dans des balises <%...%> o Les pages JSP ont lextension .jsp

Linterprteur JSP gnre une classe de servlet .java par JSP

o des variables accessibles dans des pages (session, application, request, response)
23

Directive

Exemple de JSP

<%@page import="java.util.*" %> <HTML> <HEAD> <TITLE>Test HelloWorl en JSP</TITLE> </HEAD> <BODY> Scriptlet <% out.println("Hello world !"); out.println("Hello " + request.getParameter("name"); %> <p>Today is <%= new Date() %> </BODY> </HTML> Expression 24

interprtation script
Cot serveur

<HTML> <BODY> <%="Hello world !"%>

<script type="text/javascript"> <! var now = new Date(); document.write("today is " + now.getDay()); //--> </script>

</BODY></HTML>

interprtation serveur
Cot client

Vue utilisateur

Hello world Today number is 19

<HTML> <BODY> Hello world !

<script type="text/javascript"> <! var now = new Date(); document.write("today is " + now.getDay()); //--> </script>

interprtation client

</BODY></HTML>

25

variables prdfinies JSP


out : flux de sortie dans la rponse HTTP au client.
o utiliser println()

request : objet reprsentant la requte HTTP


o utiliser getParameter("name"), getCookies(), forward()

response : objet reprsentant la rponse HTTP


o out est retourne par response.getWriter() o utiliser setCookie(new Cookie("name","value"))

session : objet reprsentant la session HTTP


o utiliser setAttribute("name"), getAttribute("name"), removeAttribute("name") o La session de lutilisateur est retourner par request.getSession(false) o request.getSession(true) cre et retourne une nouvelle session (dconnexion ou logout)

pageContext : objet reprsentant le contexte d'une page


Facilite l'accs au contexte de l'application web utiliser setAttribute("name") pour donner des paramtres aux taglibs Utiliser foward("url") pour dlguer la rponse une autre page

formulaire et JSP
Champs des formulaires directement dans des variables :
<FORM ACTION="test.jsp" METHOD="POST"> Votre nom : <INPUT TYPE=TEXT NAME="nom"> Votre ge : <INPUT TYPE=TEXT NAME="age"> <INPUT TYPE=SUBMIT VALUE="Ok"> </FORM>

Dans test.jsp, lobjet request contient les saisies: <% request.getParameter("nom") request.getParameter("age") %>

On peut crire en rponse dans test.jsp: ... Bonjour <% out.println(request.getParameter("nom")); %> ...

27

syntaxe JSP
<% %> : scriptlet <%! > : dclaration servlet <%! int myVariable = 0; %> <%-- Voici un commentaire JSP --%> <%= %> : expression (pas de ; final) <%@... %> : directive <%@page import="", <%@include page="url" <jsp:> : tag jsp <jsp:include>, <jsp:forward> TagLib JSTL <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
Librairie URI core Format XML SQL hYp://java.sun.com/jsp/jstl/core hYp://java.sun.com/jsp/jstl/fmt hYp://java.sun.com/jsp/jstl/xml hYp://java.sun.com/jsp/jstl/sql Prxe c fmt x sql

Fonctions hYp://java.sun.com/jsp/jstl/functions fn

Autres TagLib : Struts2, Tiles, Spring MVC, etc.

Forward vs redirect
Forward utilisable dans un mme war Redirect sinon redirect <jsp:forward page="/jsp/welcome.jsp"/> Page B Page C

Page A

forward
this.getServletCong().getServletContext().getRequestDispatcher( "/JSP/Demo.hello.jsp").forward(request,response);

Forward pour les erreurs


Page1.jsp

Nb pizza incorrect
-2

<% if (nbPizza<=0) { %> <jsp:forward page="Page1.jsp"> <jsp:param name=errMsg" value=Nb pizza incorrect" /> </jsp:forward> <% } %>

Page 2.jsp

Utilisation des taglibs 1/2


Rajout des jars correspondant dans WEB-INF/lib
o WEB-INF/lib/jstl.jar o WEB-INF/lib/standard.jar

Exemple :
<%@ taglib uri="hYp://java.sun.com/jsp/jstl/fmt" prex="fmt" %> <html><body> <% pageContext.setAYribute("now",new java.util.Date()); %>" <fmt:formatDate paYern="yyyy-MM-dd" value="${now}" /> </body></html>

Utilisation des taglibs 1/2


code HTML <jsp:useBean id=user class=com.acme.EndUser scope=session /> code HTML <? user.setName(Dupont); ?> <h2>Welcome, <c:out value="${user.name}/>

Ou <? EndUser user = new EndUser(); user.setName(Dupont); ?> <h2>Welcome, ${user.name}

Conteneur Web couche de persistance


JDBC Transaction

Architecture webapp

Java DataBase Connectivity


Librairie dinterfaces java qui dnisse la communica/on avec Application une base de donnes Java Package java.sql
JDBC DriverManager Oracle JDBC Driver

o classe DriverManager , interface Driver dmarrage dune connexion MySQL JDBC Driver o interfaces Connec/on , DatabaseMetaData Ges/on dune connexion et cra/on de requtes SQL o interface Statement et spcialisa/ons ges/on, excu/on dune requte SQL MySQL o interfaces ResultSet , ResultsetMetaData ges/on des rsultats de requte SQL

Oracle

Connexion via JDBC


Classe DriverManager
o DriverManager.getConnec/on(url,user,password)

Interface java.sql.Connec/on
o Gre la connec/on la base close(), getMetaData() o Cra/on d'une nouvelle requte Statement stmt = createStatement(); prepareStatement("select a from b where c=?") o pour op/misa/on, ? = paramtre, ordre important prepareCall("? = call proc_stock[?,?]") o procdure stocke (a`en/on la portabilit !) o Ges/on du transac/onnel commit(), rollback(), setAutoCommit(boolean)

Temps d'excution long considrer comme monothread

Exemple de connexion
/** retourne une connection une base de donnes accessible via JDBC * @param dbURL - URL de la base de donnes * @param driverClassName - nom complet de la classe qui sert de driver JDBC * @param user - nom de compte utilisateur de la base de donnes * @param password - mot de passe associ au compte utilisateur */ public Connection connect(String dbURL, String driverClassName, String user, String password) throws Exception { // configure le DriverManager pour charger le driver try { Object drv = Class.forName(driverClassName).newInstance(); } catch( Exception e) { e.printStackTrace(); throw e; } Connextion connection = null; try { connection = DriverManager.getConnection(dbURL, user, password); return connection; } catch( SQLException se) { se.printStackTrace(); throw se; } }

Exemple de update
Connec/on cnx = DriverManager.getConnec/on("jdbc:mysql://localhost:3306/ pizzadb","com.mysql.jdbc.Driver","user","****"); PreparedStatement updateVentes = cnx.preparedStatement( "UPDATE CAFE SET VENTE = ? WHERE NOM_CAFE LIKE ?"); updateVentes.setInt(1,50); updateVentes.setString(2, "Colombian"); updateVentes.executeUpdate(); Statement s` = cnx.createStatement(); s`.executeQuery("UPDATE CAFE SET VENTE = 50 WHERE NOM_CAFE LIKE 'Colombian' ");

Statement reprsente une requte

Requtes via JDBC

o Excution dune requte SQL Resulset res = statement.executeQuery("select "); int nbRows = statement.executeUpdate("update "); o Pagination des rsultats setMaxRows(n), getMoreResults() o contrle de lexcution de la requte setQueryTimeout(int seconds), cancel()

PreparedStatement, CallableStatement
o set<Type>(nparam,valeur) avec pour <Type> : String, Long, Double, BigDecimal, Boolean, Date, etc.

Resultset reprsente le rsultat dune requte


o mthodes principales : get<Type>(nom_colonne) next() o exemple: while(rst.next()) { ges/on d une ligne } getMetaData()

Rsultats via JDBC

ResultsetMetaData dcrit le rsultat (= la table si select * )


o getColumnCount(), getColumnType() isNullable(), getColumnLabel(), etc.

Exemple de insert
Pizza p = new Pizza("royale","tomato"); Statement s` = cnx.createStatement(); int nbLigneCrees = s`.executeUpdate("INSERT INTO pizza (pizza_name,pizza_type) VALUES ('"+p.getPizzaName()+"','"+p.getPizzaType()+"')", Statement.RETURN_GENERATED_KEYS); ResultSet generatedKeys = s`.getGeneratedKeys(); if (generatedKeys.next()) { p.setId(generatedKeys.getLong(1)); }

MySQL ALTER TABLE pizza CHANGE pizza_id pizza_id BIGINT( 20 ) NOT NULL AUTO_INCREMENT

// affiche les noms des cplonnes puis chaque ligne de rsultat de la requte Statement stmt = connection.createStatement(); ResultSet rst = stmt.executeQuery("select c.chatRoomName, t.topicName, c.language, from ChatRoom c, TopicCategory t where c.topicCategoryId = c.Id order by topicName, chatRoomName"); ResultSetMetaData rstData = rst.getMetaData(); Collection<ChatRoom> chatRooms = new Vector<ChatRoom>(); while(rst.next() == true) { ChatRoom chatRoom = new ChatRoom();

Exemple de select

chatRoom.setRoomName(rst.getString("chatRoomName")); ... chatRooms.add(chatRoom);

// fermeture de la requte et de ses Resultset associs stmt.close();

Transactions sous MySQL


Transactions en SQL o BEGIN, COMMIT, ROLLBACK, CHECKPOINT o option AUTOCOMMIT o Note : les DDL (create, alter, drop table) sont toujours AUTOCOMMIT Accs concurrents : ligne ou table bloque jusquau commit ou rollback o LOCK TABLE o SELECT FOR UPDATE o Gestion optimistes des accs concurrents

Moteurs pour la base MySQL


o o o o

InnoDB : foreign keys, select for update, stockage optimis MyISAM : plus rapide en lecture MEMORY : pas de stockage sur le disque NDBCluster : table rpartie sur plusieurs serveurs

43

Illustration dune transaction


Table possessions (dactions par utilisateurs)
id action quantite cote 1 2 3 Total Axa EDF 200 500 150 utilisateur version 2 1 4 solde 3200 1540 2030 utilisateur A B C 149,90 C 36,50 B 82,20 A id 1 2 3

Table comptes

Scnario 1 : lutilisateur A achte 200 actions Axa lutilisateur B pour 37 euros


44

gestion optimiste des accs concurrents


Scnario 1
id action quantite cote 1 2 3 4 Total Axa EDF Axa 200 300 500 150 200 36,50 82,20 36,50 id 1 2 3 utilisateur version 2 2 1 4 1 solde 1350 3390 2030 utilisateur A B C B A A 149,90 C

Scnario 2 : lutilisateur C achte aussi 400 actions Axa lutilisateur B pendant le scnario 1
45

Exemple de transaction JDBC


cnx.setAutoCommit(false); PreparedStatement updateVentes = cnx.prepareStatement( "UPDATE CAFE SET VENTE = ? WHERE NOM_CAFE LIKE ?"); updateVentes.setInt(1,50); updateVentes.setString(2, "Colombian"); updateVentes.executeUpdate(); PreparedStatement updateTotal = cnx.prepareStatement( "UPDATE CAFE SET TOTAL = TOTAL + ? WHERE" + "NOM_CAFE LIKE ?"); updateTotal.setInt(1,50); updateTotal.setString(2,"Colombian"); updateTotal.executeUpdate(); cnx.commit();

Cet exemple ne gre pas les accs concurrents

Log4j
Introduction au systme de trace cot serveur

Log4j
Librairie de gnration de traces dans un fichier Utiliser des fichiers de log au lieu de System.out Types de traces : ERROR, INFO, DEBUG Installation : log4j-<version>.jar dans le CLASSPATH Logger : gnrateur de la trace Appender : destination de la trace LayoutPattern : format de la trace Configuration
o Log4j.properties o Log4j.xml

Exemple de cong. log4j


<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d %t %c{2} - %m%n"/> </layout></appender> <category name="fr.isen"> <priority value="DEBUG"/> </category> <root> <priority value="ERROR"/> <appender-ref ref="ConsoleAppender"/> </root></log4j:configuration>

Exemple de code log4j


public class DAOBase { ... final static Logger logger = Logger.getLogger(DAOBase.class); ... public void aMethod() { ... connection = DriverManager.getConnection(dbURL, user, pwd); if(logger.isDebugEnabled()) { logger.debug("connected to " + dbURL); } ....

Junit
Introduction aux tests unitaires et l'intgration continue

JUnit
Cadriciel de cration de tests unitaires Gnration de tests unitaire possible depuis Eclipse Un test unitaire teste une mthode ou une fonction
o diffrent des tests fonctionnels qui testent les fonctions de lapplication,

Lancement possible depuis Eclipse Code isoler en gestion de configuration


o sous src/test

Exemple de junit
import static org.junit.Assert.*; import org.junit.Test; public class StringTest { @Test public void testConcatenation() { String foo = "abc"; String bar = "def"; assertEquals("abcdef", foo + bar); } @Test public void testStartsWith() { String foo = "abc"; assertTrue(foo.startsWith("ab")); } }

Connection cnx = null @Before public void setUp() throws Exception { cnx = new DAOBase().getConnection( dbUrl,dbDriver, dbUser, dbPassword); }

@Test(expected = NullPointerException.class) public void methodCallToNullObject() { Object o = null; o.toString(); }

Mthode dassertion
Mthode assertEquals assertFalse Rle Vrie que deux objets sont gaux, avec la mthode equals() Vrie que l'expression est fausse

assertNotNull Vrie que l'objet n'est pas nul assertNotSame Vrie que deux rfrences ne sont pas les mmes assertNull assertSame assertTrue fail Vrie qu'un objet est nul Vrie que deux rfrences sont les mmes, avec loprateur == Vrie que l'expression est vrai Provoque l'chec du test

Junit depuis Eclipse


Cration : bouton droit sur une classe, puis New, Other, Java, Junit, TestCase Gnerer le code de test sous un autre rpertoire /test Utilisation : bouton droit sur une Junit puis Run As, Junit Test

Tests unitaires
Un test unitaire teste une mthode ou une fonction
o diffrent des tests fonctionnels qui testent les fonctions de lapplication,

Tests unitaires automatiss


o lancs aprs la construction dun excutable o Utiliss pour lintgration continue
Compilation Tests unitaires Documentation Contrle qualit Dploiement

Tests unitaires dintgration


o lancs aprs linstallation dune application o Fonctionnement interne o Fonctionnement de lIHM

Les dveloppeurs livrent leurs modifications en continu

Processus de lintgration continue


A intervalle rgulier ltat du rfrentiel de sources est vrifi

En cas de modifications, lusine logicielle procde la construction du projet

1
Rfrentiel des sources SCM

6
Consultation des mtriques qualit Notifications

Log4J - JUnit

Rcupration des sources

Compilation

Dveloppeurs

Packaging et dploiement

Excution des tests unitaires

4
Usine logicielle

En cas dchec, la rsolution du problme devient la priorit de l'quipe

7
Tests

Calcul de mtriques qualit

Gnration de documentation

Testeurs

Environnement de dveloppement, dintgration ou de recette

57

JNDI
Introduction l'informatique distribu et RMI

Objets distribu
Prinpices : o Faire cooprer des logiciels entre eux o Avoir des "variables globales" au rseau o Utiliser et rpartir la puissance de calcul et de stockages sur plusieurs serveurs
o Appeler une mthode d'un objet se trouvant sur une autre machine exactement de la mme manire que sil se trouvait au sein de la mme machine o Pouvoir retrouver un objet existant d'aprs son nom Client
ObjetStub

Serveur
ObjetServant

Middleware

Comment sont vu les objets.


Mode classique
Interface

Mode distribu
Implementation

Squeleton

Objet

Stub

Application
Machine 1

Application
Machine 1

Machine 2
60

Utilisation de l'annuaire
3 - Appel l'objet Client Serveur

2- Recherche un objet
Object o = envCtx.lookup("MyObj");

1- Dclare un objet Annuaire

Technologies Objets distribus


Technologie RPC CORBA RMI SOAP (WebService) WCF HTTP+REST+XML/JSON Responsable IETF OMG Oracle (ex Sun) W3C Microsoft ?, pas de norme C, C++ tous java tous .Net tous

Java RMI
Remote Method Incocation Permet du code client d'appeler une mthode sur un objet serveur Java distant. simplification de CORBA pour java uniquement. Gnrateur de code Stub et Skeleton partir d'une interface : rmic Annuaire d'objet serveur disponible rmiregistry Package java.rmi Disponible dans Java SE

63

JNDI
Java Naming and Directory Interface Service de nommage / annuaire pour JEE API accs aux annuaires
javax.naming Service Provider par annuaire cible (LDAP, NIS, RMI registry)

Utiliser dans JEE pour accder des


DataSources UserTransaction EJB Etc.

JEE est une volution de CORBA pour Java

$tomcat/webapps/myapp/META-INF/context.xml
o o o o o o o o o <Resource name="jdbc/PizzaDB" auth="Container" type="javax.sql.DataSource" username="root" password="root" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/pizzadb" maxActive="8" maxIdle="4"/>

Dclarer une DataSource dans Tomcat


Cration dune DataSource dans Tomcat

Utilisation dune DataSource

$tomcat/webapps/myapp/WEB-INF/web.xml
o <resource-ref> o <res-ref-name> o jdbc/PizzaDB o </res-ref-name> o <res-type> o javax.sql.DataSource o </res-type> o <res-auth> o Container o </res-auth> o </resource-ref>

Context initCtx = new InitialContext(); Context envCtx = (Context) initCtx.lookup("java:comp/env"); DataSource ds = (DataSource) envCtx.lookup("jdbc/PizzaDB");

Construction de livrables
Ant - Maven

Ant
http://ant.apache.org Outil pour construire un livrable jar, war, ear Remplace les fichiers "make" Intgrer Eclipse (dmarrage, configuration) Doc. sous $ANT_HOME/docs/manual/index.html et http://ant.apache.org/manual/tasksoverview.html

Suite sur le support de cours Ant de T. Dandelot

EJB
EJB Session JPA JMS/MDB

EJB
Enterprise Java Beans Cadriciel de logique mtier cot serveur Sappuie sur Java SE et les APIs de Java EE Gestion dclarative :
JNDI, JTA/JTS, JDBC, JMS, JAAS
personnalisation par annotations (@... dans le code) ou descripteur de dploiement (xml)

"Portable" sur les diffrents conteneurs EJB

Architecture 4 tiers JEE


Browser WEB Container

T2
JDBC JMS JTA

html

T1

HTTP

Servlets JSPs

jdbc

T4

T1+T2
Applets java/ash

RMI / IIOP Appel local JVM SOAP, REST RMI / IIOP


EJBs

JCA JAAS
JavaMail

DB
xxxx T4
EIS

T3

T1+T2
public static void

JNDI EJB Container

main() { Java Application

Java EE Application Server

Services du conteneur d'EJB


Annuaire de composants EJB et de ressources Grappe de ressource (pool) Transactions Persistance Rpartition de charge Scurit

interface d'un EJB


Dclare l'annotation @Remote Dclare les mthodes mtier C'est une vue cliente et distante de lEJB Paramtres passs par copie
Retour et exceptions galement Doivent implmenter Serializable

import javax.ejb.Remote; ... @Remote public interface PizzaManager { public Long orderPizza(PizzaOrder po, EndUser eu); ...

Implmentation d'un EJB


Implmente les mthodes de linterface Remote Peut hriter dun autre EJB, ou dun POJO Spcifie les caractristiques de dploiement par annotations
type d'EJB (Stateless, Stateful, Message) transactions, scurit, persistance webservice

Exemple de code
Serveur
@Stateless(mappedName="PizzaManager") Public class PizzaManagerBean implements PizzaManager { public Long orderPizza(PizzaOrder po, EndUser eu) { ...

Client distant
Context ctx = new InitialContext(); PizzaManager pm = (PizzaManager)ctx.lookup( "java:global/PizzaEAR/PizzaFrontOce/PizzaManagerBean"); ... pm.creatPizzaOrder(po);

Client local
@EJB(name="PizzaManager") private PizzaManager pizzaMgr; // Injection dEJB local

EJB Session
Ralisation dactions sur demande de clients Objets mtier gestionnaire non persistants
Ce n'est pas une entit mtier sauver en base de donnes

Session Stateless ou Stateful Un Bean Stateful gre un ltat


il est plus difficile de le dupliquer

Caractristiques de dploiement
Stateless Session Bean
Grappe dinstances possible Appels de mthodes " idempotent "

Stateful session / Activation / Passivation


@PostActivate aprs activation @PrePassivate avant passivation

Pour tous les Session Beans


Callbacks @PostConstruct et @PreDestroy @TransactionManagement(value=TransactionManagementType.BEAN) @RolesAllowed("front-office","back-office"} )

EJB : Conguration & Dploiement


Descripteur de dploiement :
META-INF/ejb-jar.xml <enterprise-beans> Description du Bean (Stateful, Stateless, ...) Ressources (Base de donnes,...) Securit: permissions et rles Transactionnels </enterprise-beans>

Priorit au descripteur de dploiement sur les annotations.

Descripteur de dploiement (optionnel)


Bean Session <enterprise-beans> Lien entre <session> interfaces et <description>EJB PizzaShop</description> implmentation <ejb-name>PizzaManager</ejb-name> <business-remote>...PizzaManagerRemote</business-remote> <ejb-class>...PizzaManagerBean</ejb-class> <session-type>Stateless</session-type> Bean <transaction-type>Bean</transaction-type> ou <resource-ref> Container <res-ref-name>jdbc/facturationDB</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> </session> Ressource : </enterprise-beans> ici, base de donnes

Injection de dpendances
Variable dinstance initialise par le conteneur
Alternative au lookup JNDI Interne une application JEE serveur uniquement

Dans un client d'EJB (par exemple une Servlet)


@EJB(mappedName="java:global/PizzaEAR/PizzaFrontOffice/ PizzaManagerBean") private PizzaManager pizzaMgr; // Injection dEJB local

Dans l'EJB
@Resource(name="java:/PizzaDS") javax.sql.DataSource ds; // Injection de ressource via nom JNDI

Gestion des erreurs


Exception mtier
o o o o L'utilisateur est la cause de l'erreur ou peu la rsoudre Le dveloppeur doit crer des exception mtier qui : hritent de java.lang.RuntimeException Utilisent l'annotation @ApplicationException(rollback=true)

@ApplicationException(rollback=true) public class BusinessException extends RuntimeException { ....

Exception technique
o Rutiliser les exceptions disponibles ServletException, dans les servlets et JSP EJBException dans les EJB SQLException dans les DAO

Packaging EAR
EAR /lib JAR JAR JAR

EJB- JAR EJB- JAR

WAR http://localhost:8080/Pizza/

/META-INF/application.xml

<application><display-name>PizzaEAR</display-name> <module><ejb>PizzaEJB.jar</ejb></module> <module> <web> <web-uri>PizzaFrontOce.war</web-uri> <context-root>Pizza</context-root> </web> </module> </application>

Rappel sur le chargement de classes


Les classloaders sont hirarchiss Rgle :
1. Cherche la classe dans le cache de son niveau 2. Demande la classe au classloader parent 3. Si ClassNotFoundError pour le parent alors cherche la classe son niveau 4. Si toujours pas trouv alors ClassNotFoundError

o o o

Hierarchie standard (hors JEE), du pres aux fils


Bootstrap : java.* Extension : $JRE_HOME/ext/*.jar System (ou application si non JEE) : $CLASSPATH

Gestion du classpath JEE


Module EAR Classpath 1. All JARs in the /lib directory of the EAR 2. Manifest Class-Path of any JARs in 1 1. EJB-JAR le itself 2. JARs referenced by manifest Class-Path of EJB-JAR 3. JARs referenced by manifest Class-Path of above JARs (in 2) 1. 2. 3. 4. EJB-JAR

WAR

Retour la ligne WEB-INF/classes JARs in WEB-INF/lib obligatoire ! JARs referenced by manifest Class-Path of WAR JARs referenced by manifest Class-Path of JARs in 2 and 3

Exemple : META-INF/MANIFEST.MF de Pizza.war dans Pizza.ear

Class-Path: lib/PizzaBiz.jar PizzaEjb.jar lib/log4-j1.2.16.jar lib/jackson-databind-2.0.6.jar lib/jackson-core-2.0.6.jar

Rpartition de charge : notations


Un noeud (machine) qui hberge un ou plusieurs serveurs
web

Un conteneur Web Un serveur qui hberge un conteneur Web

ejb

Un conteneur EJB Un serveur qui hberge un conteneur EJB

web

ejb

web ejb

Un serveur qui hberge un conteneur Web et un conteneur EJB

Apache mod_jk

Un serveur Apache avec le module mod_jk

Rpartition de charge : scenarii (1)


Rpartition du serveur JavaEE

Compact

Rparti (au sein d un mme nud)

Rparti

web ejb

web

ejb

web

ejb

Rpartition de charge : scenarii (2)


(1) (2)
web ejb Apache mod_jk Apache mod_jk web ejb

web ejb

web

ejb

Rpartition de charge EJB

(3)
web

Rplication session http


web ejb

(4)
ejb

Apache mod_jk

Apache mod_jk

web

web

ejb

Rpartition de charge depuis un load balancer

Gestion des transactions


Utilisation de JTA
o javax.transaction.UserTransaction o Contrle de la transaction (timeout, rollbackOnly) o Exemple : UserTransaction utx = (UserTransaction) ctx.lookup("java:comp/UserTransaction"); utx.begin(); utx.commit();

Gestion dclarative des transactions


Au niveau de la mthode de l'EJB
Required (valeur par dfaut) Supports
Si pas de transaction, nouvelle transaction Si transaction courante, lutiliser Si transaction courante, elle est suspendue Nouvelle transaction (s'il y a un transaction courante, elle est suspendue) Exception si pas de transaction courante Exception si transaction courante

NotSupported RequiresNew Mandatory Never

Gestion dclarative des Transactions par annotations


@TransactionManagement(javax.ejb.TransactionManagementType.CONTAINER) public class Facturation implements FacturationRemote { @TransactionAttribute(javax.ejb.TransactionAttributeType.REQUIRED) public void creerFacture( ) { // }

NotSupported Required RequiresNew Mandatory Supports Never

dploiement : Gestion dclarative des Transactions par xml


<assembly-descriptor> <container-transaction> <method> <ejb-name>Facturation</ejb-name> <method-name>*</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction> NotSupported ... Required </assembly-descriptor> RequiresNew Mandatory Supports Never

Persistance + Transactions
DB1
Conteneur EJB

EJB1
DD

no cust

DB2

DBM

REG

JMX

server2

EJB http Web

T1

Conteneur WEB

Servlet 2-phase commit JTM

Conteneur EJB

EJB2 DBM

JMX

EJB

JMX

T2

Appli client

server1

server3

Java Persistence API

JPA

Un diagramme de classes mtier correspond un modle de base de donne relationnel Annotations de correspondance objet-relationnel
o Dclaration des tables et colonnes correspondantes o Dclaration des associations o Dclaration de l'hritage

Utilisation de JPA dans le code java

Framework : Hibernate, EclipseLink, ObjectDB, OpenJPA


Alternatives : JDO, JDBC

Annotations JPA
Annotations insrer dans les classes mtier pour dfinir le mapping objet relationel Annotations JPA
o Classe mtier : @Entity @Table(name="<nom_table>") @MappedSuperClass : pour les classes mre abstraites o Attributs dans classe mtier : @Column(name="<nom_colonne>", length=<taille>, nullable=<true|false>) @Id : la colonne est lidentifiant unique de la table @GeneratedValue : valeur non fournie par le dveloppeur @Version : colonne technique utilise pour la gestion optimiste daccs concurrents @Transient : ignor par JPA (non sauv)
94

@Entity @Table(name="pizzaorder") public class PizzaOrder implements Serializable { // Serializable conseill public PizzaOrder () { } // Constructeur par dfaut obligatoire @Id @GeneratedValue(strategy=GenerationType.IDENTITY) public Long id; @Column(name="order_date") private Date orderDate; Nom de colonne dirent

Exemple 1/2
Pour MySQL Autoincrement

@ManyToOne(fetch=FetchType.LAZY,cascade=CascadeType.REFRESH) @JoinColumn(name="enduser_id") protected EndUser customer; ___________________________________ Associations (1 EndUser , N PizzaOrder) @Entity @Table(name="enduser") public class EndUser implements Serializable { ... @OneToMany(mappedBy="customer", cascade=CascadeType.ALL, fetch=FetchType.LAZY) private Collection<PizzaOrder> pizzaOrders;

Associations
Exemple : EndUser OneToMany PizzaOrder
Le propritaire de la relation correspond la table qui possde la cl trangre
Lien EndUser/PizzaOrder : PizzaOrder est propritaire de la relation Attribut mappedBy ct EndUser, et joinColumn ct PizzaOrder

OneToOne

Exemple : EndUser et Address Exemple : EndUser vers PizzaOrder Exemple : PizzaOrder vers EndUser Exemple : Pizza et PizzaOrder

OneToMany ManyToOne

ManyToMany

Jointures en JPA
@ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="<nom_colonne>", unique=true, nullable=true) @OneToMany(mappedBy="<nomAttributClasseAssocie>", cascade=CascadeType.ALL) @ManyToMany @JoinTable(name="<nom_table>",

joinColumns = @JoinColumn(name ="<nom_colonne>"), inverseJoinColumns = @JoinColumn(name ="<nom_colonne>")

OneToOne : idem ManyToOne d'un cot et OneToMany de l'autre CascadeType : ALL, MERGE, PERSIST, REFRESH, REMOVE, DETACH FetchType : LAZY, EAGER
97

Cascade
CascadeType ALL PERSIST MERGE REMOVE REFRESH DETACH READ NONE

@ManyToMany(mappedBy="pizzas",cascade= ?) private Collection<PizzaOrder> pizzaOrders = null;


Eet

Tous les eets ci-dessous, valeur par dfaut Si l'entit crer possde des entits dans l'association concerne, alors elles sont cres galement Si l'entit modier possde des entits dans l'association concerne, alors celles-ci sont modies (ou cres) galement Si l'entit supprimer possde des entits dans l'association concerne, alors celles-ci sont supprimes galement Si l'entit relire possde des entits dans l'association concerne, alors celles-ci sont relues galement ("undo" des modications) Si l'entit dtacher possde des entits dans l'association concerne, alors celles-ci sont dtaches galement N'existe pas ! car il s'agit du fetch=FecthType.EAGER N'existe pas ! car il s'agit du fetch=FecthType.LAZY

public class PizzaOrder implements Serializable { ... @ManyToMany(fetch=FetchType.LAZY) @JoinTable(name="pizzadetail", joinColumns=@JoinColumn(name="order_id"), inverseJoinColumns=@JoinColumn(name="pizza_id")) private Collection<Pizza> pizzas = null; .... __________________________ idem OneToMany d'un cot public class Pizza implements Serializable { ... @ManyToMany(mappedBy="pizzas") private Collection<PizzaOrder> pizzaOrders = null; ...

Exemple 2/2

Facultatif,

La configuration de la persistance par JPA est dans META-INF/persistence.xml


<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.0" xmlns="hYp://java.sun.com/xml/ns/persistence" xmlns:xsi="hYp://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="hYp://java.sun.com/xml/ns/persistence hYp:// java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <persistence-unit name="PizzaPU"> <jta-data-source>java:/PizzaDS</jta-data-source> <class>fr.isen.eleve.todo.pizza.biz.EndUser</class> <class>fr.isen.eleve.todo.pizza.biz.Pizza</class> <class>fr.isen.eleve.todo.pizza.biz.PizzaOrder</class> <properties> <property name="showSql" value="true"/> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" /> <property name="hibernate.hbm2ddl.auto" value="validate" /> </properties> ou create, </persistence-unit> create-drop, </persistence> update

Conguration JPA

100

Instructions JPA
La classe EntityManager manipule les donnes
EntityManagerFactory emf = @PersistenceContext(unitName="PizzaPU") Persistence.createEntityManagerFactory private EntityManager em; ("<persistanceunitname>"); EntityManager em = emf.createEntityManager();
JPA em.persist(e) em.merge(e) em.remove(e) SQL insert update delete

em.nd(e.class,id) select

em.flush() : sauvegarde immdiate des modifications em.refresh(e) : annulation de modifications em.createQuery(<requte en ejbQL avec :param >) em.createNativeQuery(<requte en SQL>) em.getTransaction().begin(); em.getTransaction().commit();

101

Gestion des entits


... public void orderPizza(PizzaOrder po, EndUser eu) { EndUser eu = persistenceManager.find(eu.getClass(),eu.getId()); po.setCustomer(eu); persistenceManager.persist(po); ...

appel nd() pour meYre dans le contexte obligatoire si CascadeType.ALL non dni

Non gre gre persit(), merge(), find(), query()

Refresh() et cascade d'entit non gre interdite

new

detach() garbage collector

Exemple
@Stateless public class FacturationBean implements FacturationRemote { @PersistenceContext private EntityManager entityManager; public void creerFacture(String numfact, double montant) { Facture fact = new Facture(numfact); fact.setMontant(montant); entityManager.persist(fact); } public Facture getFacture(String numfact) { return entityManager.find(Facture.class, numfact); } }

1 seule table pour toutes les sous-classes @Entity @Inheritance(strategy=SINGLE_TABLE) @DiscriminatorColumn(name="<nom_colonne>", discriminatorType=STRING,length=20)

Dnition de l'hritage

Conseill Dconseill

1 table par sous-classe classe mre @Entity @Inheritance(strategy=InheritanceType.JOINED)


@Entity @PrimaryKeyJoinColumn(name="ID", referencedColumnName="ID")

1 table par sous-classe classe lle

Classe mre abstraite 1 table par classe @MappedSuperClass @Entity @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)

EJB-QL
Langage proche de SQL
select p from Pizza p From sur les classes au lieu des tables Respectez la casse dans le nom de la classe (package facultatif) "update" et "delete" "inner join", "group by having", "order by"
Liste des commanes avec leur client dont le nom commence par :lastname avec leur factures

public List<Facture> listFactures( ) { Query q = em.createQuery("select po from PizzaOrder join fetch po.pizzas where po.customer.lastname like =:lastname"); q.setParameter("lastname","perez"); return q.getResultList();
ou q.getSingleResult() ou q.executeUpdate() selon les requtes

Annotation de Callbacks d'une entite


Mthodes appeles par le persistenceManager
Annotation de callback @PrePersist @PostPersist @PreUpdate @PostUpdate @PreRemove @PostRemove @PreLoad @PostLoad Description Avant insertion en base Aprs insertion en base Avant mise jour en base Aprs mise jour en base Avant suppression en base Aprs suppression en base Avant lecture en base Aprs lecture en base

Bean Validation
String @NotNull @Size @PaYern Int, Long @Min @Max

Dclaration de contrainte
@NotNull @Size(max=50) public String getNom()

Validation de donnes dans une instance Contraintes dclares par annotations java
Float, Double @DecimalMin Date @Future

@DecimalMax @Past

Validation ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); Validator validator = factory.getValidator(); Set<ConstraintViolation<DeveloppeurSeniorBean>> constraintViolations = validator.validate(personne); if (constraintViolations.size() > 0 ) {

Bonnes pratiques JPA


Utiliser java.lang.Long pour l'id technique Utiliser java.util.Set pour les associations Toujours dclarer le type de fetch dans les associations Privilgier FecthType.LAZY sur toutes les associations
o Utiliser "join fetch" dans les requtes JPQL

Utiliser @NamedQuery Utiliser une Query d'update plutt que t = em.find(Thing.class,id); t.setF(t); em.flush(); Dfinir les entits JPA puis gnrer les tables lorsqu'il n'y a pas d'existant

Exemple @NamedQuery
@Entity @Table(name="pizza") @NamedQueries( @NamedQuery( name="findAllPizzas", query="select p from Pizza p" ) ) public class Pizza implements Serializable {

@Stateful @RolesAllowed( { "frontoffice", "backoffice" } ) public class EndUserManagerBean ...

Dclaration de la scurit par annotation

L'identit (nom) d'un client est aussi appele Principal Les rles et les Realm (user /password) sont dclars par configuration au niveau du serveur chaque serveur dispose de mcanismes spcifiques

Dclaration de la scurit par DD


<assembly-descriptor> Dfinition de rle ... <security-role> <description>Application front-office</description> <role-name>front-office</role-name> </security-role> Permissions <method-permission> accordes <role-name>front-office</role-name> un rle <method> <ejb-name>EndUserManager</ejb-name> <method-name>authenticate,chgPassword</method-name> </method> </method-permission> </ assembly-descriptor>

Вам также может понравиться

  • 0708 Prog3 TP03C
    0708 Prog3 TP03C
    Документ4 страницы
    0708 Prog3 TP03C
    Said Gahi
    Оценок пока нет
  • 1 2 Document
    1 2 Document
    Документ55 страниц
    1 2 Document
    Said Gahi
    Оценок пока нет
  • Langage Assembleur PC
    Langage Assembleur PC
    Документ204 страницы
    Langage Assembleur PC
    donsallus
    Оценок пока нет
  • Examen SQL
    Examen SQL
    Документ2 страницы
    Examen SQL
    Bouriche Tawfik
    80% (5)
  • Serie 6
    Serie 6
    Документ2 страницы
    Serie 6
    Said Gahi
    Оценок пока нет
  • 2 PresentationMerise
    2 PresentationMerise
    Документ14 страниц
    2 PresentationMerise
    Said Gahi
    Оценок пока нет
  • Exo Pert
    Exo Pert
    Документ6 страниц
    Exo Pert
    delpiere2003
    60% (5)
  • Access 2003
    Access 2003
    Документ62 страницы
    Access 2003
    Ismael Abdou Saley
    Оценок пока нет
  • M1esfi BD
    M1esfi BD
    Документ0 страниц
    M1esfi BD
    Said Gahi
    Оценок пока нет
  • Wap WML
    Wap WML
    Документ4 страницы
    Wap WML
    Said Gahi
    Оценок пока нет
  • Conduite de Projets TD
    Conduite de Projets TD
    Документ10 страниц
    Conduite de Projets TD
    Makhlouk Mohsine
    Оценок пока нет
  • 0708 Prog TP03
    0708 Prog TP03
    Документ1 страница
    0708 Prog TP03
    Said Gahi
    Оценок пока нет
  • 0708 Prog3 TD05C
    0708 Prog3 TD05C
    Документ7 страниц
    0708 Prog3 TD05C
    Said Gahi
    Оценок пока нет
  • C01 2
    C01 2
    Документ14 страниц
    C01 2
    Said Gahi
    Оценок пока нет
  • 08 POSD Colle02
    08 POSD Colle02
    Документ2 страницы
    08 POSD Colle02
    Said Gahi
    Оценок пока нет
  • 04 Interaction
    04 Interaction
    Документ15 страниц
    04 Interaction
    yousson0706
    Оценок пока нет
  • 0708 PROG3 Projet
    0708 PROG3 Projet
    Документ3 страницы
    0708 PROG3 Projet
    Said Gahi
    Оценок пока нет
  • Corrige TD9
    Corrige TD9
    Документ5 страниц
    Corrige TD9
    Diablessse
    100% (1)
  • 0708 PROG3 Examen
    0708 PROG3 Examen
    Документ2 страницы
    0708 PROG3 Examen
    Said Gahi
    Оценок пока нет
  • 0507 Prog3 TD04
    0507 Prog3 TD04
    Документ2 страницы
    0507 Prog3 TD04
    Said Gahi
    Оценок пока нет
  • 0708 PROG3 Partiel
    0708 PROG3 Partiel
    Документ2 страницы
    0708 PROG3 Partiel
    Said Gahi
    Оценок пока нет
  • 0507 Prog3 TD01
    0507 Prog3 TD01
    Документ2 страницы
    0507 Prog3 TD01
    Said Gahi
    Оценок пока нет
  • Conduite de Projets TD
    Conduite de Projets TD
    Документ10 страниц
    Conduite de Projets TD
    Makhlouk Mohsine
    Оценок пока нет
  • 0507 Prog3 TD02
    0507 Prog3 TD02
    Документ2 страницы
    0507 Prog3 TD02
    Said Gahi
    Оценок пока нет
  • 0708 PROG3 Examen
    0708 PROG3 Examen
    Документ2 страницы
    0708 PROG3 Examen
    Said Gahi
    Оценок пока нет
  • TD-TP 5
    TD-TP 5
    Документ1 страница
    TD-TP 5
    Said Gahi
    Оценок пока нет
  • KP I Catalogue Formations
    KP I Catalogue Formations
    Документ8 страниц
    KP I Catalogue Formations
    Said Gahi
    Оценок пока нет
  • 0708 Prog TP03
    0708 Prog TP03
    Документ1 страница
    0708 Prog TP03
    Said Gahi
    Оценок пока нет
  • 6th Central Pay Commission Salary Calculator
    6th Central Pay Commission Salary Calculator
    Документ15 страниц
    6th Central Pay Commission Salary Calculator
    rakhonde
    100% (436)
  • RAPPORT DE STAGE LIPOQS Court
    RAPPORT DE STAGE LIPOQS Court
    Документ14 страниц
    RAPPORT DE STAGE LIPOQS Court
    Omaima Garani
    Оценок пока нет
  • Loi 5-96
    Loi 5-96
    Документ26 страниц
    Loi 5-96
    Manal Maddah
    Оценок пока нет
  • Politique de Prix
    Politique de Prix
    Документ5 страниц
    Politique de Prix
    Fiedano Behivoka
    Оценок пока нет
  • GC1 Rapport-Du-Visite TPPGC
    GC1 Rapport-Du-Visite TPPGC
    Документ8 страниц
    GC1 Rapport-Du-Visite TPPGC
    Labidi Adem
    Оценок пока нет
  • Etude Géotechnique: 1-Analyse Granulométrique
    Etude Géotechnique: 1-Analyse Granulométrique
    Документ11 страниц
    Etude Géotechnique: 1-Analyse Granulométrique
    Aziz Hwewi
    Оценок пока нет
  • ET Parafoudre
    ET Parafoudre
    Документ45 страниц
    ET Parafoudre
    Oi69qEZ
    Оценок пока нет
  • 317-1-01 Demande Des Prestations Suite Au Décès de L'assuré (E)
    317-1-01 Demande Des Prestations Suite Au Décès de L'assuré (E)
    Документ2 страницы
    317-1-01 Demande Des Prestations Suite Au Décès de L'assuré (E)
    Rashid Atfaoui
    Оценок пока нет
  • Expose Reseau Multi Debit
    Expose Reseau Multi Debit
    Документ26 страниц
    Expose Reseau Multi Debit
    Hama Mossi Abdoul Razak
    Оценок пока нет
  • Implantation Dun Batiment
    Implantation Dun Batiment
    Документ105 страниц
    Implantation Dun Batiment
    Ninou Fares
    Оценок пока нет
  • Définition Du BCR
    Définition Du BCR
    Документ11 страниц
    Définition Du BCR
    salim Bnsf
    Оценок пока нет
  • ZKLKZ
    ZKLKZ
    Документ20 страниц
    ZKLKZ
    housssem benhani
    Оценок пока нет
  • Formation Adobe Photoshop Elements 2022
    Formation Adobe Photoshop Elements 2022
    Документ2 страницы
    Formation Adobe Photoshop Elements 2022
    Patrick baobab341free.fr
    Оценок пока нет
  • Chapitre1 Hydraulique PDF
    Chapitre1 Hydraulique PDF
    Документ24 страницы
    Chapitre1 Hydraulique PDF
    Mustapha El Metoui
    Оценок пока нет
  • Cinema Paradiso Love Theme - Partitura Completa PDF
    Cinema Paradiso Love Theme - Partitura Completa PDF
    Документ6 страниц
    Cinema Paradiso Love Theme - Partitura Completa PDF
    jeanhuillipan
    Оценок пока нет
  • Activite3 Microbit
    Activite3 Microbit
    Документ2 страницы
    Activite3 Microbit
    J P
    100% (1)
  • Sujet D'entrainement N°1
    Sujet D'entrainement N°1
    Документ2 страницы
    Sujet D'entrainement N°1
    Kacem Benlabsir
    Оценок пока нет
  • Offre de Services TEXYS
    Offre de Services TEXYS
    Документ9 страниц
    Offre de Services TEXYS
    Boris Fogue
    Оценок пока нет
  • Climat Des Affaires Au Maroc
    Climat Des Affaires Au Maroc
    Документ3 страницы
    Climat Des Affaires Au Maroc
    Youssef El Ouali
    Оценок пока нет
  • Catalogo PAM Def-Nuovo PDF
    Catalogo PAM Def-Nuovo PDF
    Документ64 страницы
    Catalogo PAM Def-Nuovo PDF
    Said Mansour Mohamed
    100% (1)
  • Cours Route
    Cours Route
    Документ17 страниц
    Cours Route
    Boubacar Diallo
    Оценок пока нет
  • 20181211152016623.en.fr
    20181211152016623.en.fr
    Документ22 страницы
    20181211152016623.en.fr
    Luc Mutombo Mukulu
    Оценок пока нет
  • Prez CDG Approfondi - Introduction
    Prez CDG Approfondi - Introduction
    Документ27 страниц
    Prez CDG Approfondi - Introduction
    FatimaZahra Alyoune
    Оценок пока нет
  • La Boîte À Outils Du Journaliste Web - Nicolas Becquet
    La Boîte À Outils Du Journaliste Web - Nicolas Becquet
    Документ18 страниц
    La Boîte À Outils Du Journaliste Web - Nicolas Becquet
    Nicolas Becquet
    Оценок пока нет
  • Master 2020 Fin
    Master 2020 Fin
    Документ88 страниц
    Master 2020 Fin
    Elbahi Djaalab
    Оценок пока нет
  • Ruu 600
    Ruu 600
    Документ27 страниц
    Ruu 600
    Ismail Ahdach
    Оценок пока нет
  • 01 Chimieorganique2005
    01 Chimieorganique2005
    Документ15 страниц
    01 Chimieorganique2005
    jijax-ukob
    Оценок пока нет
  • Installation Serveur W2K
    Installation Serveur W2K
    Документ9 страниц
    Installation Serveur W2K
    strideworld
    100% (1)
  • E38 PDF
    E38 PDF
    Документ6 страниц
    E38 PDF
    Hicham Omr
    Оценок пока нет
  • BELAID LITIM Grave
    BELAID LITIM Grave
    Документ60 страниц
    BELAID LITIM Grave
    Тереть Вот
    Оценок пока нет