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

Java Discussion :

NullPointerException après utilisation de wget


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Juin 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 98
    Par défaut NullPointerException après utilisation de wget
    Bonjour,
    j'ai fais un morceau de code dans lequel j'utilise la commande système wget (je sais pas trop si c'est connu, wget est utilisé pour aspirer un site, voilà) grâce à exec():

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Runtime.getRuntime().exec("wget http://fr.wikipedia.org/wiki/" + nom + " -O " + nom);
    Je récupère donc des pages de wikipédia.

    Ensuite, je souhaite utiliser ces pages. Pour cela, j'ouvre et je lis ces pages avec un Scanner.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    ...
    try {
         reader = new BufferedReader(new FileReader(nomPage));
    } catch(FileNotFoundException fnfe) {
         System.out.println("Erreur d'ouverture");
       }
     
    Scanner scanner = new Scanner(reader);
     
    while (scanner.hasNext()) {
         ...
    }
    Et voila.
    Alors mon souci est que je récupère une gentille NullPointerException

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Exception in thread "main" java.lang.NullPointerException: source
    ...
    J'ai l'impression que j'utilise les fichier alors qu'ils ne sont pas encore enregistrés sur mon disque. En gros, le programme execute la lecture du fichier avant d'avoir fini le wget et donc je lis un fichier qui n'existe pas.

    Déjà, je voudrais savoir si cette hypothèse est valide, si elle convient à quelqu'un et ensuite, si quelqu'un sait comment faire pour contrer ce problème.
    Merci.

  2. #2
    Membre chevronné Avatar de let_me_in
    Inscrit en
    Mai 2005
    Messages
    441
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 441
    Par défaut
    esssaie avec ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Runtime.getRuntime().exec("sh -c \"wget http://fr.wikipedia.org/wiki/" + nom + " -O " + nom+"\"");

  3. #3
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    Le NullPointerException est levé sur quelle ligne ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Par défaut
    Le problème vient du fait que le Runtime.getRuntime().exec(...) crée un nouveau thread dans lequel la commande est exécutée.

    Tu as donc deux threads en cours. L'un exécute le wget (c'est un thread lent, vu qu'il se charge d'IO spécifiques et que WP a un ping important), l'autre continue ton code. Comme le premier thread est (bien) plus rapide, il arrive et voit qu'il n'existe pas de fichier comme tu l'indiques. Donc... NullPointerException.

    Tu dois donc attendre la fin de l'exécution du premier thread pour continuer ton code.

    Au passage, le wget n'est pas là pour "aspirer" un site, mais pour récupérer des données HTTP et les copier sur le disque. Que ce soit une page, un site complet ou un fichier particulier, ça n'aspire que si tu le demandes

  5. #5
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Salut,


    Est-ce que tu attends la fin du process avant de lire le fichier ?
    Est-ce que tu lis bien les flux d'entrée/sortie de wget ?

    Bref il y a plusieurs règles à respecter lorsqu'on exécute un programme externe Exécuter une application externe en Java


    Mais si c'est pour télécharger un fichier, pourquoi ne pas passer directement par la classe URL ?



    Enfin je vois une grossière dans ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    try {
         reader = new BufferedReader(new FileReader(nomPage));
    } catch(FileNotFoundException fnfe) {
         System.out.println("Erreur d'ouverture");
       }
     
    Scanner scanner = new Scanner(reader);
    Si le fichier n'existe pas tu attrapes bien l'exception mais tu continues quand même à lire le fichier



    Citation Envoyé par dingoth Voir le message
    Le problème vient du fait que le Runtime.getRuntime().exec(...) crée un nouveau thread dans lequel la commande est exécutée.
    Cela crée un nouveau processus à part entière et non pas un thread !


    a++

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Par défaut
    Certes, mais le fond est bien là : la concurrence fait qu'il y a deux programmes qui tournent ensembles et qu'on n'est même pas certain que wget ait déjà créé le fichier dans lequel il inscrira les données de Wikipédia.

  7. #7
    Membre confirmé
    Inscrit en
    Juin 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 98
    Par défaut
    esssaie avec ça :
    Code :

    Runtime.getRuntime().exec("sh -c \"wget http://fr.wikipedia.org/wiki/" + nom + " -O " + nom+"\"");
    ça ne marche plus, les page wikipédia ne sont plus enregistrées sur mon disque.


    Le NullPointerException est levé sur quelle ligne ?
    le NullPointerException est levé sur la déclaration du Scanner. Apparemment, le reader est null.

    Pour utiliser une commande avec des paramètres, le mieux est de passer par un tableau de chaînes de caractères, en utilisant la méthode exec(String[]) de Runtime: ça permet dans la plupart des cas de régler proprement les problèmes d'espaces et de quotes.
    Juste pour être sur d'avoir bien compris, c'est somme ça que je dois faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    String[] tabString = {"wget http://fr.wikipedia.org/wiki/", nom, " -O ", nom};
    Runtime.getRuntime().exec(tabString);
    Si c'est bien comme ça, ça ne fonctionne pas, je ne comprend pas trop pourquoi.

    Le problème vient du fait que le Runtime.getRuntime().exec(...) crée un nouveau thread dans lequel la commande est exécutée.

    Tu as donc deux threads en cours...
    C'est ce qui me faisais peur...
    Tu dois donc attendre la fin de l'exécution du premier thread pour continuer ton code.
    Puis-je demander comment on fait?
    Au passage, le wget n'est pas là pour "aspirer" un site, mais pour récupérer des données HTTP et les copier sur le disque. Que ce soit une page, un site complet ou un fichier particulier, ça n'aspire que si tu le demandes
    Ok, merci

    Est-ce que tu attends la fin du process avant de lire le fichier ?
    Non, je ne sais pas comment on fait...
    Est-ce que tu lis bien les flux d'entrée/sortie de wget ?
    Euh... non, je lance juste la commande wget et ensuite je lis avec java...je ne sais pas non plus comment on fait...

    Bref il y a plusieurs règles à respecter lorsqu'on exécute un programme externe Exécuter une application externe en Java
    Faut que je lise ça!

    Certes, mais le fond est bien là : la concurrence fait qu'il y a deux programmes qui tournent ensembles et qu'on n'est même pas certain que wget ait déjà créé le fichier dans lequel il inscrira les données de Wikipédia.
    Oui, c'est mon problème, et je ne sais pas comment faire.

  8. #8
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Franchement si c'est pour télécharger une page utilises directement la classe URL :
    • C'est 100% portable
    • Tu n'as pas à t'embêter avec la gestion des flux des processus


    a++

  9. #9
    Rédacteur
    Avatar de CyberChouan
    Homme Profil pro
    Directeur technique
    Inscrit en
    Janvier 2007
    Messages
    2 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 752
    Par défaut
    Pour utiliser une commande avec des paramètres, le mieux est de passer par un tableau de chaînes de caractères, en utilisant la méthode exec(String[]) de Runtime: ça permet dans la plupart des cas de régler proprement les problèmes d'espaces et de quotes.
    Avant de poster, pensez à regarder la FAQ, les tutoriaux, la Javadoc (de la JRE que vous utilisez) et à faire une recherche
    Je ne réponds pas aux questions techniques par MP: les forums sont faits pour ça
    Mes articles et tutoriaux & Mon blog informatique

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [dll] libérer une dll apres utilisation
    Par polo54 dans le forum API standards et tierces
    Réponses: 12
    Dernier message: 11/07/2009, 22h48
  2. Question sur l'utilisation de wget
    Par berry dans le forum Réseau
    Réponses: 7
    Dernier message: 24/05/2007, 22h46
  3. "Access violation" apres utilisation des compos BD
    Par bahaa dans le forum Bases de données
    Réponses: 1
    Dernier message: 06/10/2005, 07h59
  4. [JPox] NullPointerException aprés un SELECT
    Par MinsK dans le forum Persistance des données
    Réponses: 3
    Dernier message: 05/07/2005, 13h46
  5. [FB] installation et apres? utilisation ???
    Par vad dans le forum Débuter
    Réponses: 7
    Dernier message: 17/02/2005, 09h55

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