IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

avec Java Discussion :

Problème Unhandled exception dans un enum


Sujet :

avec Java

  1. #1
    Membre du Club
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Novembre 2010
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Novembre 2010
    Messages : 61
    Points : 42
    Points
    42
    Par défaut Problème Unhandled exception dans un enum
    Bonjour,

    J'ai ce message erreur : unhandled exception type SlickException

    Je précise que j'utilise le type Image du moteur 2D Slick mais comme c'est un type Enum, je ne sais pas du tout où placer le throw exception =x

    Quelqu'un peu m'aider ?

    Voici le code source :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    public enum TypeTile 
    {	
            //Le problème est ici à cause du new Image(...) dont eclipse me dit qu'il faut qu'ai un unhandled expection mais je ne vois pas du tout comment faire :s
    	pierre ("base", new Image("images/tile_pierre.png"), false, 0);
     
    	private String nom;
    	private Image img;
    	private boolean collidable;
    	private int calque;
     
     
     
    	private TypeTile(String nom, Image img, boolean collidable, int calque)
    	{
    		this.nom = nom;
    		this.img = img;
    		this.collidable = collidable;
    		this.calque = calque;
    	}
     
    	public int getCalque() {
    		return calque;
    	}
     
    	public String getNom() {
    		return nom;
    	}
     
     
    	public Image getImg() {
    		return img;
    	}
     
    	public boolean isCollidable() {
    		return collidable;
    	}
    }
    Merci d'avance !

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 552
    Points : 21 608
    Points
    21 608
    Par défaut
    En principe, les constructeurs des enums (et n'importe quelle initialisation de n'importe quelle classe d'ailleurs) ne doivent pas pouvoir lancer d'exception du tout, ou du moins, éviter autant que possible que cela puisse arriver.

    Parce que si ça arrive, le programme ne se charge même pas, il ne commence pas son point d'entrée, et il n'y a aucun moyen de gérer l'exception pour afficher un beau message d'erreur.

    Il vaudrait mieux que ton type énuméré n'essaie pas de charger les images, ou au moins pas à la déclaration. Au pire il sera toujours temps de lancer une exception quand quelqu'un appelle getImg().

    Si vraiment il n'y a pas le choix, deux possibilités de s'en tirer :

    # 1 : modifier le constructeur pour qu'il prenne le chemin de l'image, et pas l'image, en paramètre, et lui faire catcher l'exception :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public enum TypeTile 
    {	
      PIERRE("base", "images/tile_pierre.png", false, 0);
     
      TypeTile(String nom, String imagePath, boolean collidable, int calque) {
        try {
          Image image = new Image(imagePath);
          // ...
        } catch(SlickException e) {
          throw new IllegalStateException(e.getMessage(), e);
        }
      }
    }
    ou

    # 2 : faire une méthode statique qui construit l'image à partir de son chemin et catche l'exception.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public enum TypeTile 
    {	
      PIERRE("base", makeImage("images/tile_pierre.png"), false, 0);
     
      private static Image makeImage(String path) {
        try {
          return new Image(imagePath);
        } catch(SlickException e) {
          throw new IllegalStateException(e.getMessage(), e);
        }
      }
     
      TypeTile(String nom, Image image, boolean collidable, int calque) {
        // ...
      }
    }
    Comme déjà dit, si jamais l'exception est bel et bien lancée, le programme ne démarrera pas, et rien ne peut être géré pour afficher un joli message.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par thelvin Voir le message
    Comme déjà dit, si jamais l'exception est bel et bien lancée, le programme ne démarrera pas, et rien ne peut être géré pour afficher un joli message.
    On peut très bien utiliser Thread.setDefaultUncaughtExceptionHandler() pour intercepter ce genre d'exception


    a++

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 552
    Points : 21 608
    Points
    21 608
    Par défaut
    D'accord, j'ai pas mal exagéré la réalité, mais enfin, le principe est là : s'il y a exception à l'initialisation d'une classe, c'est pas un simple try catch qui va gérer et c'est pas souple du tout.
    Bon courage pour se rendre compte que c'est parce qu'il n'a pas trouvé les images. Du coup, la différence entre ça et pas de contrôle du tout, elle est pas toujours évidente.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par thelvin Voir le message
    D'accord, j'ai pas mal exagéré la réalité, mais enfin, le principe est là : s'il y a exception à l'initialisation d'une classe, c'est pas un simple try catch qui va gérer et c'est pas souple du tout.
    Ben justement... Cela ne sert à rien de déporter les try/catch. Qu'il soit à l'initialisation ou ailleurs le problème est le même. Que va-t-on faire lors du prochain try/catch ???

    Surtout que cela risque de multiplier les try/catch à chaque fois que tu accèdera à l'enum , et que cela multiplie donc le risque de mauvais traitement des exceptions.

    En clair au lieu d'avoir un FileNotFound au plus tôt, on se retrouve avec un NullPointerException à l'autre bout du code


    Citation Envoyé par thelvin Voir le message
    Bon courage pour se rendre compte que c'est parce qu'il n'a pas trouvé les images. Du coup, la différence entre ça et pas de contrôle du tout, elle est pas toujours évidente.
    Ben justement : en remontant l’exception immédiatement, tu obtiens l'erreur immédiatement

    Le fait de remonter une "unchecked-exception" n'est pas sale ni moins bien. Au contraire même !!!

    Si on peut gérer une alternative c'est bien de le faire. Par exemple dans le cas où le fichier d'image provient de l'utilisateur, on peut lui indiquer que le fichier n'existe pas et l'inviter à ressaisir le chemin... Mais si on n'a aucune alternative, autant laisser remonter l'erreur au plus tôt !




    Si on est en mode console c'est "parfait" puisqu'on a notre erreur immédiatement (et pas trois heure après quand on a le malheur de faire le getImage()).

    Le seul soucis c'est en mode graphique et/ou multithread, où on n'a pas forcément de vue sur la console.
    Les unchekced-exceptions pouvant tuer un thread tout en laissant le programme continuer.

    On peut pallier à cela via l'UncaughtExceptionHandler. Par exemple rien qu'avec ce petit bout de code, on a déjà quelque chose d'acceptable :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    class ErrorHandler implements Thread.UncaughtExceptionHandler {
    	public void uncaughtException(Thread t, Throwable e) {
    		// On transforme le stacktrace en "String" :
    		StringWriter writer = new StringWriter();
    		e.printStackTrace(new PrintWriter(writer));
    		String text = writer.getBuffer().toString();
     
    		// On crée une zone de texte pour afficher le stacktrace :
    		JTextArea textArea = new JTextArea(text);
    		JScrollPane scroll = new JScrollPane(textArea);
    		scroll.setPreferredSize(new Dimension(400, 200));
     
    		// On affiche une boite de dialogue avec toutes les informations :
    		Object[] message = {
    				"Le programme va s'arrêter car une erreur inattendue est survenue.",
    				"Merci de contacter le support technique.",
    				" ",
    				"Thread : " + t.getName(),
    				" ",
    				"Détail : ",
    				scroll
    		};
    		JOptionPane.showMessageDialog(null, message,
    			"Erreur d'application", JOptionPane.ERROR_MESSAGE);
     
    		// On quitte :
    		System.exit(0);
    	}
    }
    Avec cette simple instruction en début de programme, on gère alors les unchecked-exceptions en affichant un message avant de quitter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Thread.setDefaultUncaughtExceptionHandler(new ErrorHandler());



    On peut même y greffer une remonté d'info automatique par email ou autre



    a++
    Images attachées Images attachées  

  6. #6
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 552
    Points : 21 608
    Points
    21 608
    Par défaut
    Pas faux dans certains cas. Dans d'autres, c'est plus difficile d'accepter de planter pratiquement tout y compris ce qui n'a rien à voir, juste parce que des ressources fichier ne sont pas trouvées.

    Je trouve qu'un enum, par nature, devrait laisser le choix. Mais bon, c'est du chipotage.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Pas faux dans certains cas. Dans d'autres, c'est plus difficile d'accepter de planter pratiquement tout y compris ce qui n'a rien à voir, juste parce que des ressources fichier ne sont pas trouvées.
    C'est sûr que cela dépend des besoins...

    Mais dans le cas d'une image livré avec ton application, je trouve cela à la fois cohérent et pratique. C'est le concept du "fail-fast".
    Plutôt que de tenter de continuer le programme dans un état incorrect, il est préférable de l'arrêter au plus tôt avec les informations les plus utiles




    En effet si l'exception ne devrait normalement jamais arrivé pourquoi s'embêter à la gérer ailleurs où à gérer des valeurs null. Autant planter le programme immédiatement.



    Un exemple : dans un jeu d’échec tu charges les images correspondant à chaque pièce.
    Si l'image du Roi est illisible que faire ? Continuer au risque de planter plus tard avec une cause moins évidente (un nullpointer qui sort de nulle part) ? Ou pire d'afficher le programme avec des éléments en moins (un plateau d'echec sans "Roi" c'est un peu bête )


    Bien sûr qu'il y a des cas où il y a un intérêt à traiter les exceptions, mais les "checked-exceptions" nous force à les traiter systématiquement... Ce qui ne devrait pas être le cas.


    a++

  8. #8
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 552
    Points : 21 608
    Points
    21 608
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Un exemple : dans un jeu d’échec tu charges les images correspondant à chaque pièce.
    Si l'image du Roi est illisible que faire ?
    Il faut planter aussi tôt que possible.
    Mais ce n'est pas une raison pour planter le programme serveur, qui n'affiche des trucs que dans la console et n'a aucun besoin d'images, mais qui utilise la même classe énumérée. Surtout si les images en question sont fournies sur le filesystem et pas dans le classpath.

    Citation Envoyé par adiGuba Voir le message
    Bien sûr qu'il y a des cas où il y a un intérêt à traiter les exceptions, mais les "checked-exceptions" nous force à les traiter systématiquement... Ce qui ne devrait pas être le cas.
    Je n'essaie pas de discuter sur les checked ou unchecked, même si c'est à cause de ça que le programme ne compile pas.
    Je dis que ce n'est pas le rôle du chargement d'une classe de les lancer, ni l'une ni l'autre. C'est plutôt le rôle du chargement de la configuration.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #9
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Mais ce n'est pas une raison pour planter le programme serveur, qui n'affiche des trucs que dans la console et n'a aucun besoin d'images, mais qui utilise la même classe énumérée.
    Bien sûr il faut adapter à chaque cas !

    Pour une application serveur, l'UncaughtExceptionHandler servira à répondre un message d'erreur sans tout arrêter


    a++

Discussions similaires

  1. Problème d'exception dans Wicket avec CXF
    Par Nico87 dans le forum Services Web
    Réponses: 1
    Dernier message: 10/03/2010, 14h20
  2. problème dans mon enum
    Par salseropom dans le forum C
    Réponses: 3
    Dernier message: 31/03/2009, 13h07
  3. Problème Unhandled exception
    Par Mickael Baron dans le forum C#
    Réponses: 10
    Dernier message: 21/04/2008, 22h34
  4. Réponses: 6
    Dernier message: 25/09/2007, 13h33
  5. probléme d'exception dans un formulaire
    Par minie dans le forum Struts 1
    Réponses: 2
    Dernier message: 05/06/2007, 11h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo