problème avec UndeclaredThrowableException !!!

problème avec UndeclaredThrowableException !!! - Java - Programmation

Marsh Posté le 20-04-2007 à 20:20:54    

Salut !
 
Je suis en train de faire un projet sur l'utilisation de Proxy en Java !
Ce projet consiste à gérer une liste distante située sur un serveur web.  
L'accès à cette liste se fait via un code java qui utilise un proxy et qui envoie une url paramétrée de la forme http://monServeur.fr/liste.html?nom=liste_001&commande=ajouter&elt=item1.
Cette url servira donc à exécuter la commande/méthode ajouter sur la liste nommée liste_001, pour insérer l'élément item1.
Selon l'architecture du patron (design pattern) "Procuration/Proxy" on nous demande de coder le proxy de façon à filtrer les méthodes à la volée. Soit, on a une liste de méthodes (ex. ajouter(), retirer(), vider(), toString(), taille() ...) qu'on doit examiner à chaque fois qu'une commande/méthode est invoquée dans l'url.
En autre, les noms des méthodes autorisées sont transmis lors de la création du mandataire, celui-ci lèvera une exception du type IllegalAccessException si on tente d'accéder via une méthode non-autorisée.
Voici comment se présente mon programme :
J'ai une classe :
------------------------------------------------------------------

Code :
  1. public class ListeProxyAvecFiltrage implements Liste<String>, InvocationHandler{
  2.  private Liste<String> listeProxy;
  3.  private Liste<String> listeInitiale;
  4.  private String[] methods = null ;
  5.  
  6.  /**
  7.   * Crée une liste distante nommée accessible via le réseau.
  8.   * Cette liste dispose d'un filtre de méthodes qui, seront
  9.   * passées en paramètres.
  10.   *
  11.   * @param String[] methodesAutorisees - Liste des méthodes autorisées.
  12.   */
  13.  public ListeProxyAvecFiltrage(String[] methodesAutorisees)
  14.  {
  15.    // Liste locale
  16.    this.listeInitiale = new ListeImpl();
  17.    // Liste distante
  18.    this.listeProxy    = new ListeProxyHttp("liste_830605" );
  19.    // Liste des méthodes autorisées à l'invocation.
  20.    this.methods       = methodesAutorisees;  
  21.  }
  22.  
  23.  /**
  24.   * Inspecte si une méthode est présente dans une liste donnée de méthodes.
  25.   *
  26.   * @param String[] listOfMethods - Représente la liste de méthodes
  27.   * @param  String element - L'élément dont il faut vérifier la présence
  28.   * @return boolean - VRAI si l'élément est dans la liste de méthodes, FAUX sinon
  29.   */
  30.  private boolean contains(String[] listOfMethods, String element)
  31.  {    
  32.    for(String e : listOfMethods)
  33.    {  
  34.        if(element.equals(e)){ return true; }
  35.    }    
  36.    return false;
  37.  }
  38.  
  39.  /**
  40.   * Ajoute un élément dans la liste.
  41.   *
  42.   * @return boolean - VRAI si l'élément est ajouté dans la liste, FAUX sinon.
  43.   * @param String elt - L'élément à ajouter.
  44.   */  
  45.  public boolean ajouter(String elt){
  46.    return listeProxy.ajouter(elt);
  47.  }
  48.    
  49.  /**
  50.   * Vide la liste.
  51.   *
  52.   * @return boolean - VRAI si la liste s'est vidée complètement, FAUX sinon.
  53.   */
  54.  public boolean vider(){
  55.    return listeProxy.vider();
  56.  }
  57.   // Idem pour les méthodes retirer(), taille(), toString(), estPresent() ...
  58.  
  59. }


------------------------------------------------------------------
 
dont la méthode invoke() s'écrit comme suit :
 
------------------------------------------------------------------
 

Code :
  1. public Object invoke(Object proxy, Method m, Object[] args)
  2.  throws Throwable
  3.  {
  4.   try
  5.    {                  
  6.      if( contains(this.methods, m.getName()) ){
  7.          System.out.println("Invocation autorisée de |"
  8.                               + m.getDeclaringClass().getName()
  9.                               + "|." +  m.getName());
  10.                              
  11.          return m.invoke(this, args);
  12.      }
  13.      else{
  14.          System.out.println("Invocation non-autorisée de |"
  15.                            + m.getDeclaringClass().getName()
  16.                            + "|." + m.getName());
  17.                            
  18.          throw  new IllegalAccessException("\n\tAccès illégal de |"
  19.                                + m.getDeclaringClass().getName()
  20.                                + "|." + m.getName()
  21.                              );
  22.      }
  23.    }
  24. //     catch(InvocationTargetException ite)
  25. //     { System.out.println("<InvocationTargetException> levée dans l'invocation de " + m.getName());    }
  26. //     catch(IllegalArgumentException  iae)
  27. //     { System.out.println("<IllegalArgumentException> levée dans l'invocation de "  + m.getName());    }
  28. //     catch(NullPointerException      npe)
  29. //     { System.out.println("<NullPointerException> levée dans l'invocation de "      + m.getName());    }
  30.    catch(Throwable     t)
  31.    {
  32.      throw new IllegalAccessException
  33.     ("<IllegalAccessException> propagée dans l'invocation de " + m.getName() + "\nCause : " + t.getCause());
  34.    }
  35.  }


------------------------------------------------------------------
 
Quand je crée le proxy dans le programme de test de JUnit je mets :
 
------------------------------------------------------------------

Code :
  1. public class ListeProxyAvecFiltrageTest extends junit.framework.TestCase{
  2.    public void testAccesRestreint() throws Exception{
  3.      
  4.        Liste<String> l =
  5.                  new ListeProxyAvecFiltrage(
  6.                  new String[]{"ajouter","estPresent","taille","toString"});
  7.                  
  8.        Liste<String> lpaf = (Liste<String> )Proxy.newProxyInstance(
  9.                                                        Liste.class.getClassLoader(),
  10.                                                        new Class[]{Liste.class},
  11.                                                        (ListeProxyAvecFiltrage)l);            
  12.        lpaf.ajouter("titi" );
  13.        lpaf.ajouter("toto" );
  14.        
  15.        System.out.println("Ma liste avant vider() : " + lpaf);
  16.        
  17.        assertTrue(lpaf.taille() == 2);
  18.        
  19.        try{
  20.          lpaf.vider();
  21.          fail("Attention, une exception est attendue ici !" );        
  22.        }
  23.        catch(Throwable t){
  24.          System.out.println("|Throwable| t : " + t.getCause());
  25.          t.printStackTrace();
  26.          
  27.          System.out.println("t est-il une instance de IllegalAccessException ? "
  28.          + (t instanceof IllegalAccessException));
  29.          
  30.          // Ici l'assertion retourne toujours faux à l'exécution
  31.          // ce qui fait échouer les tests !!!!
  32.          assertTrue( t instanceof IllegalAccessException);
  33.        }
  34.    }  
  35. }


------------------------------------------------------------------
En exécutant le programme, le résultat donne :

Code :
  1. Invocation autorisée de |question1.Liste|.ajouter
  2. Invocation autorisée de |question1.Liste|.ajouter
  3. Invocation autorisée de |java.lang.Object|.toString
  4. Liste.toString() avant vider() : |titi, toto|
  5. Invocation autorisée de |question1.Liste|.taille
  6. Invocation non-autorisée de |question1.Liste|.vider
  7. |Throwable| t : java.lang.IllegalAccessException: <IllegalAccessException> propagée dans l'invocation de vider
  8. Cause : null
  9. t instance de IllegalAccessException ? false


 
Et le Stack Trace donne :
 

Code :
  1.     at $Proxy0.vider(Unknown Source)
  2.     at question2.ListeProxyAvecFiltrageTest.testAccesRestreint(ListeProxyAvecFiltrageTest.java:26)
  3.     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  4.     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
  5.     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  6.     at java.lang.reflect.Method.invoke(Method.java:585)
  7.     at junit.framework.TestCase.runTest(TestCase.java:154)
  8.     at junit.framework.TestCase.runBare(TestCase.java:127)
  9.     at junit.framework.TestResult$1.protect(TestResult.java:106)
  10.     at junit.framework.TestResult.runProtected(TestResult.java:124)
  11.     at junit.framework.TestResult.run(TestResult.java:109)
  12.     at junit.framework.TestCase.run(TestCase.java:118)
  13.     at junit.framework.TestSuite.runTest(TestSuite.java:208)
  14.     at junit.framework.TestSuite.run(TestSuite.java:203)
  15.     at bluej.runtime.RemoteTestRunner.doRun(RemoteTestRunner.java:48)
  16.     at bluej.runtime.ExecServer.runTestMethod(ExecServer.java:680)
  17.     at bluej.runtime.ExecServer.access$700(ExecServer.java:37)
  18.     at bluej.runtime.ExecServer$3.run(ExecServer.java:882)
  19. Caused by: java.lang.IllegalAccessException: <IllegalAccessException> propagée dans l'invocation de vider
  20. Cause : null
  21.     at question2.ListeProxyAvecFiltrage.invoke(ListeProxyAvecFiltrage.java:73)
  22.     ... 18 more


 
Alors la question que je me pose est la suivante :
 
Comment est-ce qu'on peut faire en sorte que l'exception propagée soit une instance de la classe IllegalAccessException ? Si l'instance est bonne l'assertion est vérifiée normalement ! Les tests réussissent alors !

Il se trouve que les exceptions ont été traitées correctement (selon moi) ici, mais malheureusement il y en a une qui me cause problème c'est UndeclaredThrowableException ! Quelles solutions existe-t-il pour ce genre de problème ?
 
Merci d'avance pour votre aide !
Voila !  :)  
 
malinski2006


Message édité par malinski2006 le 20-04-2007 à 20:48:16
Reply

Marsh Posté le 20-04-2007 à 20:20:54   

Reply

Marsh Posté le 20-04-2007 à 20:38:30    

alors plusieurs choses :
- retire le URGENT du titre ou tu vas te faire jetter par les modos
- encadre ton code en mettant [ code = java ] [/ code] (sans les espaces)

 

ça permet ça qui rend le code bcp plus lisible

Code :
  1. public static void main(String[] args) {
  2.     System.out.println("Pouet" );
  3. }
 

Poste aussi le contenu de ta méthode vider, visiblement ça merde :)

 

et enfin, jette un coup d'oeil ici : http://java.sun.com/javase/6/docs/ [...] ption.html

 

et là http://java.sun.com/javase/6/docs/ [...] ang.Object[])

 

visiblement ta méthode distante lance une exception qui n'est pas reprise par ton proxy


Message édité par Jubijub le 20-04-2007 à 20:39:16

---------------
Jubi Photos : Flickr - 500px
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed