Manipulations

Partie I. Composants Session:

version OK Java 1.6..... avec Jbosss.1.5...

ou bien éventuellement (non testé) Java 1.7 et jboss 1.6

Etape 1 : installer et exécuter

Etape 2 : modifications de Hello STATELESS

  1. Etape facultative (ignorer si problème firewall) : utiliser un composant déployé sur le serveur d'appli d'un autre binome

Pour le faire:

ipconfig //pour avoir l'adresse IP cote serveur. Soit par exemple 192.168.0.17

//demarrer le serveur avec option --host=192.168.0.17

Run.bat --host=192.168.0.17

//cote client dans le fichier jndi.properties :

java.naming.provider.url=192.168.0.17

  1. Ajouter un résultat string a hello qui sera retourné et affiché côté client
  2. Ajouter une nouvelle méthode à Hello (par exemple addition) et l'utiliser chez le client

Etape 3

  1. Transformer les composants Hello en STATEFUL (attention un seul L)
  2. Vérifier que ça compile, et exécute correctement
  3. Vérifier que l'initialisation est correcte maintenant l'attribut "test" est toujours à zéro lors de la création
  4. transformer l'application en une application bilingue
  • Les composants sont soit initialisés en francophone, soit en anglophone
  • ajouter une méthode "switchlange()" qui bascule entre français et anglais

Partie II. Composants Entity:

Etape 1 : installer et exécuter

  1. récupérer la version fournie en download
  2. exécuter et tester qu'il y a bien persistence : arrêter le serveur d'applications et vérifier que les documents sont présents (noms et contenu)

Etape 2 : interopérabilité

  1. Etape facultative (ignorer si problème) : utiliser un composant déployé sur le serveur d'appli d'un autre binôme

Etape 3 : Modification de l'application

modification des composants

  1. ajouter une méthode "print()" aux composants "Document" pour afficher le "contenu" et le "nom"
  2. ajouter un attribut de type booléen qui permet à "print()" d'afficher les messages en anglais ou en français
  3. Tester l'accès direct au composant "Document" depuis le client : tester les invocations possibles et leur effet sur la persistance : que se passe-t-il si le client invoque setContent(....); qu'obtient-il en résultat de getContent(); et afficher_contenu(); Que se passe-t-il avec la persistence après arret et redémarrage du serveur d'application;
  4. Déclarer l'attribut Content en Transient et refaite les tests précédents

modification du client

  1. modifier le côté client pour faire un menu interactif offrant des fonctions de:
* cycle de vie d'un document de création, suppression, renommage d'un document
* fonctions: modification du contenu, consultation du contenu
* exploration du référentiel : afficher la liste de tous les documents, ou de ceux qui commencent par tel chaine de caractères.
  1. Question ouverte : comment modifier l'application pour gérer des "sous-répertoires" ? (A FAIRE EN DERNIERE PRIORITE après les questions suivantes)

Indications pour composants de type entity EJB2:

pour détruire un composant de type Entity créé avec la clef primaire "toto", utiliser la méthode home.remove("toto");

Indications pour composants (implanté par la classe Document) de type entity EJB3: Code à utiliser dans la classe GestDocBean

Détruire le document s'appelant "toto" :

	      d = manager.find(Document.class,"toto");
   	      manager.remove(d);

Récupérer la liste de tous les document :

java.util.List <Document> list= manager.createQuery("SELECT OBJECT(doc) FROM Document doc").getResultList();

Récupérer la liste de tous les document commençant par "toto" :

java.util.List <Document> list= manager.createQuery("SELECT OBJECT(doc) FROM Document doc WHERE doc.Name LIKE 'toto%' ORDER BY doc.Name").getResultList();

Autres exemples de requetes (avec utilisation de paramètre)

   public List findByLastName(String last)
   {
      System.out.println("-- CustomerDAOBean.findByLastName(id)");
      return manager.createQuery("select c from Customer c where c.last = :last").setParameter("last", last).getResultList();
   }

Code complet de méthode affiche

Code Java méthode affiche

remarque :

Attributs non persistents: utiliser l'annotation @Transient

Appartient au package : javax.persistence (si pb de compilation utiliser @javax.persistence.Transient)

Le contenu des attributs déclarés Transient n'est plus géré par le composant session qui expose le composant entity. Si on déclare Transient l'attribut content de Document alors la méthode lire donne un contenu "null", alors que si on invoque, depuis le client (après modif de créer_document pour recevoir en résultat la référence sur le document créé) la méthode getContent() on obtient le contenu correct

Aide Java:

Code java de saisie clavier:

    // Procedure de saisie de texte
    //import java.io.*;
    public static String saisir_string(String prompt)
    	{
	String input = "";
	try
	    	{
		System.out.print(prompt);
		DataInputStream dataIn = new DataInputStream(System.in);
		BufferedReader in = new BufferedReader(new InputStreamReader(dataIn));
		input = in.readLine();
	    	}
	catch(IOException ex)
	    	{
		System.err.println("Can't read from `" +  ex.getMessage() + "'");
		System.exit(1);
	    	}
	return input;
    	}

Boucles :

	String input=null;

 	try{	
            do
		{
                   input =  saisir_string("c/creer, r/renommer, s/supprimer, q/quitter: votre choix ? > ");

                   if(input.equals("c"))
			{

			    input = saisir_string("nom du document > ");;
			    try{
				// creation

			    }
			    catch (javax.ejb.CreateException e1){System.out.println("Ce document existe deja"); }
			}

                    //etc....


                } while(!input.equals("q"));
	}
	catch(IOException ex)
	    {
		System.err.println("Can't read from `" + ex.getMessage() + "'");
		System.exit(1);
	    }

Lecture, Ecriture de fichiers binaires

      public byte[] read_fichier(String Fichier) 
      	{
    	try 
		{ 
      		FileInputStream canal = new FileInputStream(Fichier);
      		byte[] contenu = new byte[canal.available()];
      		canal.read(contenu,0,canal.available());
      		canal.close();
      		return (contenu);
    		}

    	catch (FileNotFoundException ex) 
		{
      		System.err.println("Fichier introuvable");
      		return (new byte[0]);
    		}

    	catch(IOException ex)
      		{
        	System.err.println("Ne peut pas lire depuis `" + ex.getMessage() + "'");
        	return (new byte[0]);
      		}
  	}


  // Ecrit le contenu du fichier
    public void write_fichier(String Fichier, byte[] contenu)
	{
    	try 
		{ 
      		FileOutputStream canal = new FileOutputStream(Fichier);
      		canal.write(contenu); // Peut ne pas recopier le dernier octet !
      		canal.close();
    		}

    	catch(IOException ex)
      		{
        	System.err.println("Ne peut pas ecrire depuis ecrire_fichier`" + ex.getMessage() + "'");
      		}
  	}

Partie III

Intercepteurs et callback : inspirer vous de cet exemple (Le 1er notamment) pour introduire les callback et intercepteurs dans l'application de gestion de documents

[1] http://docs.jboss.org/ejb3/docs/tutorial/1.0.7/html/Callbacks_and_Callback_Handlers.html

[2] http://www.java2s.com/Code/Java/EJB3/EJBTutorialfromJBossCallbackListener.htm

      Extratit de [1]
     Stateful session bean callbacks

    * PostConstruct - is invoked when the bean is first created, after any dependency injection is done.
    * PreDestroy - is invoked when the bean is removed from the pool or destroyed. It will happen before any @Remove annotated method is invoked.
    * PostActivate
    * PrePassivate 

Solution 1 : intercepteurs dans la classe GesDocBean :

  import javax.interceptor.Interceptors;
  import javax.annotation.PostConstruct;
  import javax.annotation.PreDestroy;

  public class GestDocBean implements GestDocRemote,java.io.Serializable
  {
   @PersistenceContext
   private EntityManager manager;

   /////////////////////// AJOUTER CES CALLBACKS Definis ici
   @PostConstruct
   public void methode_resultat_void_sans_params()
   {
      System.out.println("PostConstruct - Have EntityManager: " + (manager != null));
   }

   @PreDestroy
   public void preDestroyCallback()
   {
      System.out.println("PreDestory - Have EntityManager: " + (manager != null));
   }
   /////////////////////////////////
 ////SUITE INCHANGEE

Solution 2 : intercepteurs dans classe externe

Ajouter dans GestDocBean les déclarations suivantes

  import javax.interceptor.Interceptors;
  import javax.annotation.PostConstruct;
  import javax.annotation.PreDestroy;

  ///////////////////////////////////////////////
  ///Interception dans une classe externe
  @Interceptors({LifecycleInterceptor.class}) 
  //////////////////////////////////////////////

Ajouter la classe suivante

// Classe LifecycleInterceptor.java

    package projet.referentiel.doc;

    import javax.interceptor.InvocationContext;
    import javax.annotation.PostConstruct;

   public class LifecycleInterceptor
   {
   @PostConstruct
   public void postConstruct(InvocationContext ctx)
   {
      try
      {
         System.out.println("LifecycleInterceptor postConstruct");
         ctx.proceed(); //permet de passer la main aux méthode suivantes
      }
      catch(Exception e)
      {
         throw new RuntimeException(e);
      }
   }
  }

Partie IV Définir une clef primaire composite comprenant le nom du document et le nom de son auteur en vous inspirant de cet exemple

[1] http://docs.jboss.org/ejb3/docs/tutorial/1.0.7/html/Composite_Primary_Keys_for_Entities_in_EJB3.html

Partie V inspirer vous de cet exemple pour modifier l'application de gestion de document afin de tester l'extended context persistence

http://docs.jboss.org/ejb3/docs/tutorial/1.0.7/html/Extended_Persistence_Contexts.html

Partie IV Ajouter la gestion de sécurité par les roles et le mots de passe pour l'acces aux methodes du gestionnaire

[1] http://docs.jboss.org/ejb3/docs/tutorial/1.0.7/html/Security_and_Transactions_in_EJB3.html [2] http://schuchert.wikispaces.com/EJB3+Tutorial+6+-+Security

Les sources de [1] sont sous (répertoire de l'exemple security) http://docs.jboss.org/ejb3/docs/tutorial/1.0.7/ejb3-tutorials.zip

Attention : définir autant de lignes dans roles.properties et users.properties

Partie VII

Déployer l'exemple des message driven beans.

Tutoriaux :

JBOSS (EJB3 et extensions)

[1]http://download.oracle.com/javaee/5/tutorial/doc/

Les sources des exemples de [1] sont sous http://docs.jboss.org/ejb3/docs/tutorial/1.0.7/ejb3-tutorials.zip

Hibernate (transactions, persistence, etc...)

[2] http://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html/transactions.html#transactions-demarcation

Bilan pédagogique :

Vérifier que vous êtes capable de :

  • modifier une application (déclarations XML et JAVA, implantations JAVA clients et composants) pour:
* augmenter des fonctionalités sans changer de type de composant
* transformer un composant SESSION STATELESS en SESSION STATEFUL,
* créer, rechercher, utiliser, détruire un composant ENTITY
* ajouter la sécurité : authetificatiion (login, password), contrôle d'accès basé sur les rôles