Bonjour,
Je suis actuellement en thèse en biologie, et dans le cadre de mes recherches, j'ai dû apprendre à bidouiller en Java afin de créer un programme qui soumette automatiquement des requetes HTTP. Vous l'aurez compris, je suis ARCHI débutant.
J'ai écrit un programme qui marche et qui m'a donné des résultats. Je suis passé à autre chose depuis, mais j'ai dû m'y remettre il y a quelques semaines et là surprise : cette exception apparait :
23-oct.-2006 14:16:54 org.apache.commons.httpclient.HttpMethodBase processResponseHeaders
ATTENTION: Cookie rejected: "$Version=0; ncbi_sid=D4495F7053CA9B40_0504SID; $Path=/; $Domain=.nih.gov". Domain attribute ".nih.gov" violates RFC 2109: host minus domain may not contain any dots
J'utilise la classe PostMethod, et voici le genre d'url que je rentre en paramètre :
http://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=protein&id=NZ_AEEM01000015&rettype=gb
Bon, mon programme tourne toujours mais depuis que cette exception apparait, l'analyse ne va plus à son terme, et plante au bout d'un moment. Pas de message d'erreur, juste l'exception citée plus haut qui apparait en boucle, comme si le programme tentait de faire encore et encore la même requete sans y parvenir.
Pour en avoir le coeur net, je souhaiterais modifier mon programme de telle sorte que cette exception n'apparaisse plus, et en même temps comprendre ce qu'elle signifie. Je comprends juste que l'host moins le domaine (.nih.gov) ne doit pas contenir de point.
Des idées pour m'aider???
Merci beaucoup
Julien
Bonsoir,
Jamais utilisé cette classe. Peut être (je dis bien peut être) qu'il y a un problème dedans. On dirait qu'elle perd les pédales à cause de la ribambelle de sous-noms de domaines.
J'ai fait un essai en envoyant une requête GET ou POST dans le serveur avec un simple socket client et pour moi ça fonctionne.
Voici le code
ça répond ceci:
Si tu changes GET en POST ça marche tout pareil.
Tu pourrais aussi utiliser la classe java.net.HttpURLConnection de la JDK
Je n'ai pas essayé avec cette classe faute de temps. Si j'ai le temps j'essaie et je te dis ce qu'il en est.
En espérant t'avoir aidé un peu.
Merci beaucoup, je vais essayer ça.
Comme je devais aller vite et que je ne connaissais rien à Java, j'ai ré-utilisé le code de quelqu'un qui travaillait dans mon labo avant que je n'y arrive.
Il utilisait cette classe PostMethod de la library http-commonclient. Le problème vient surement de là en effet.
Je te tiens au courant.
Julien
Ca marche pour l'instant. L'analyse est en cours...
Y'a plus qu'à croiser les doigts, ca prend en général 3-4 jours!
Merci beaucoup.
Julien
C'était avec plaisir :)
Aïe... re-problème, je m'explique.
L'analyse effectuée par mon programme nécessite d'effectuer un grand nombre de requêtes du type de celle indiquée dans mon premier post (entre 1000 et 1500 au bas mot, sur plusieurs jours). Chaque requête est censée me renvoyer tout un tas d'informations, contenues dans le fichier séquences.gb (qu'on peut simplement obtenir en entrant la requête dans la barre d'adresse du navigateur internet).
Tout va bien au début.
La 7ème requête renvoie normalement 5.11 Mo de données... et là ça coince. J'ai tout testé et c'est bien cette requête-ci qui est en cause. Je pense que la taille importante des donnés récupérées y est pour quelque chose. Concrètement, la charge du CPU passe à 100% pendant de longues minutes (la mémoire elle n'augmente pas) puis rediminue mais rien ne se passe, le programme reste bloqué sur la requête. Pas de message d'erreur, juste bloqué (et indiqué comme "not responding" dans le task manager).
Le comportement est exactement le même avec le socket ou la classe HttpURLConnection.
Une idée???
Julien
Mais ce n'est pas le même problème.
En effet et c'est bien ce que l'on voit dans l'en-tête renvoyé par le serveur et reçu par mon code d'exemple.
Toujours d'accord. le navigateur ne fait rien de plus que d'envoyer une requête GET comme mon code d'exemple le fait.
Je le pense aussi.
On peut imaginer que le serveur ne veuille pas servir un fichier trop important. Dans ce cas, le socket reste bloqué à attendre des données qui n'arrivent pas. Mais l'hypothèse est improbable.
On peut imaginer que les données ne sont pas récupérées correctement et qu'elles engorgent un tampon. Pour le savoir, il faut que tu postes un bout de code et on regardera.
Tu peux aussi poster cette 7eme requête afin que je l'essaie pour voir. (sans promesse de ma part, je n'ai pas beaucoup de temps. Mais si je peux, j'essaierai)
Improbable en effet, car j'ai déjà chargé des fichiers plus lourds par le passé avec la précédente méthode qui maintenant me bombarde de l'exception décrite dans le premier post.
Ca correspondrait plus à ce que j'observe... Mais quelle partie de mon code voudrais-tu?
C'est très gentil de ta part. Là je n'ai pas ça sous la main, mais dès mon retour au boulot demain matin je poste ça.
Merci de ton aide.
Julien
Bonjour,
Voilà la requête qui fait mal :
http://www.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=protein&id=NC_004556.1&rettype=gb
En espérant que tu auras le temps de jeter un coup d'oeil...
Julien
Je dois dire que je n'ai pas vraiment le temps, mais poussé par la curiosité j'ai regardé quand même ;)
J'ai écrit un bout de code qui récupère un fichier de 5.11 Mo de données comme prévu. Au début on a
et à la fin
Comme je ne savais pas à l'avance que c'était un fichier texte, le code que j'ai écrit lit à les octets par paquets de 1024, comme si c'était du binaire.
Du coup je me suis dit que peut être le stream que tu utilises perd les pédales à cause d'un caractère spécial ou je ne sais quoi.
Bref toujours est-il que je n'ai pas vu le moindre problème avec cette requête et le code ci-cessous:
En espérant que ce bout de code (Windows: attention au nom de fichier) te tire d'embarras.
Merci d'avoir essayé!
Ta solution marche bien effectivement. Néanmoins je préfère manipuler le BufferedReader, ça me permettait de renvoyer directement un String.
J'ai donc continué aujourd'hui mes investigations. En fait, il semble qu'avec ton premier bout de code, le fichier pour cette requête se télécharge en boucle... il arrive à la fin et recommence, coincé dans le while.
J'ai donc rajouté une condition et ça semble mieux marcher. En effet j'ai remarqué que les fichiers se terminent tous par la même série de caractères.
Pour ta curiosité, ça donne ça :
J'ai l'impression que ça fonctionne bien. Je teste ça...
Julien
J'espère bien :)
Sur le fond pourquoi pas un BufferedReader/InputStreamReader si tu es sûr que les données dans le fichiers sont toujours adaptées. Mais encore faut-il en être sûr, ce que moi je ne sais pas.
Quand à la forme... voir ci dessous
Dans tes rêves. J'ai essayé aussi par acquis de conscience, aucun problème sur cette requête. Fais une pause, réfléchis et regarde. Pour quelle raison cela téléchargerait-il en boucle ?
On ne programme jamais comme ça. Tu n'es pas certain que tous les fichiers vont se terminer comme ça. Quand on veut lire un fichier (ou un flux) jusqu'au bout, on le lit ... jusqu'au bout et cela se fait comme dans tous mes exemples de code.
Sans blague ? Ca marche mais je parie tu n'as pas fais exprès. Pardonne moi mais quelle horreur...
Quand tu fais un readLine, les caractères tels que \n sont virés et normalement la condition à la fin ne devrait pas pouvoir être testée.
En fait elle peut l'être parce que tu ajoutes un \n quand tu insères dans le StringBuffer, tu reconstruis le //\n\n mais je doute un peu que tu ais fait exprès.
Tu sais, à voir cet extrait code, j'ai très envie de penser que des erreurs tu en as fait beaucoup ailleurs. Alors au lieu de corriger mon code qui marche (si si même le premier), montre donc un peu ce que tu as écrit toi même, qui posait problème et que tu n'as jamais montré.
Pour tester la fin d'un BufferedReader, c'est bien readLine() == null qu'il faut faire. C'est même écrit dans la Javadoc.
Sincèrement je pense que tu ne cherches pas les erreurs aux bons endroits.
Rien que pour cette classe, le code fait 900 lignes. Et il y en a d'autres... Donc je sais pas vraiment par où commencer.
Je cherche peut-être les erreurs aux mauvais endroits. N'empêche que ce que j'ai écrit, ca marche sur ma machine. Manque de bol pour moi, ma machine ne sert qu'à tester car lorsque je lance le programme, je ne peux presque plus rien faire d'autre. Et quand je le lance sur la machine commune du labo, ca reste bloqué toujours à la même foutue requête. Je n'arrive vraiment pas à comprendre ce qui fait que ça peut marcher d'un côté et pas de l'autre (les OS : XP pour mon PC et XP Pro pour l'autre).
Maintenant je ne voulais absolument pas te froisser en modifiant ton code. Mais je préfère toujours chercher par moi-même avant d'appeler à l'aide. J'ai donc fait des tests de mon côté... Bon ben ca marche pas terrible mais j'aurais essayé :)
Revenons à ce programme...
Au départ, je lui balance un string et il lance un programme appelé BLAST via une requête http sur le serveur de mon labo. Pour cela j'utilise la classe HttpClient
C'est ce code que j'utilisais avant pour les requêtes qui me posent problème. Avant, ça marchait nickel.
Le résultat est un fichier XML qui est parsé afin de retirer les infos qui m'intéressent. J'utilise ces deux méthodes.
Ca, c'est pas de moi, je l'ai ré-utilisé à mon compte.
Ensuite, j'utilise les informations récoltées afin de poster une requête à un serveur US contenant d'autres informations dont j'ai besoin.
Avant, je ré-utilisait la méthode post décrite plus haut, mais comme ça ne fonctionne plus...
La boucle while (! (results.endsWith me servait en fait à tester que le fichier a bien été intégralement téléchargé. Vu les problèmes de connexion qu'on a ici, je préfère être sûr. Le fichier gb récupéré est censé être formaté afin de faciliter les choses à quelqu'un comme moi désirant le parser sans trop de problèmes. Donc oui, je suis sûr qu'ils se terminent tous en //\n\n.
(D'ailleurs, oui j'ai fait exprès de rajouter les \n. Je sais que le ReadLine ne les prend pas. Alors je les mets là où ils devraient être... volontairement.)
Le retrieve(url), c'est en fait la méthode décrite dans le post précédent.
La suite je ne l'ai pas mise, c'est juste un parseur du fichier gb, et la suite du programme...
J'imagine que tout ce que tu vois là doit te piquer les yeux. Je suis conscent du fait que, comparé à un "vrai" code, ce que j'ai écrit semble horrible. Mais bon, j'ai jamais appris, et on m'a demandé de pondre un programme en 3 mois... j'ai fait au plus pressé :)
Merci du temps que tu me consacres.
Julien
Juste une chose : ce qui m'a gêné dans ta deuxième méthode, c'est de récupérer un fichier en fait. J'ai peur que de devoir le rouvrir, le convertir en String pour le passer à la méthode suivante ralentisse le tout... l'analyse est déjà longue...
Maintenant si tu me dis que ca ne ralentiras rien du tout, je me lance :)
Julien
Ah mais ça tu ne l'avais jamais dit. Ce n'est pas une information anodine et tu aurais du la donner dès le départ.
Par contre pour l'instant je ne sais pas ce qui se passe, mais cette fois on peut imaginer que le code n'a rien à y voir. D'ailleurs mon code marche, tu l'as constaté également. Donc à priori il y a un problème avec l'autre bécane.
Ce n'est pas le problème que je sois froissé. Sur n'importe quel forum, quand quelqu'un vient demander de l'aide et qu'on lui donne (et donc que celui qui aide sait ce qu'il dit), si le quelqu'un dit "ton exemple marchait pas ou ceci ou cela", le quelqu'un attire sur lui des grognements. C'est la règle du jeu ;)
Je te suggère de le faire direct avec les sockets comme je l'ai fait. Comme ça tu es sûr au maximum de ce qui se passe.
Non et non. C'est si tu fais comme dans mes exemples, surtout comme dans le deuxième que tu seras sûr. Tu as la routine toute cuite, utilise la.
Alors ça...
Il m'est arrivé il y a longtemps de travailler avec des données scientifiques qui se présentaient sous une forme semblable à ce que tu as.
Et mon code ne marchait pas. Sais tu pourquoi ? Parce que dans un fichier, il y avait un octet mal placé. Alors le "censé être formaté" moi je n'y fais plus confiance depuis longtemps.
Maintenant pour ton problème je ne dis pas que c'est ce qui gêne. Mais tu ne devrais jamais faire confiance à ce genre de choses. C'est comme ton test de la fin des fichiers. Tu crois être sûr. Mais en réalité, tu l'est infiniment moins :(
Je n'ai pas regardé en détail (pas le temps).
La question n'est pas que ça me pique les yeux ou pas. La question est qu'il faut que tu montres du code si quelque chose ne va pas et que tu donnes aussi le maximum d'infos pour qu'il soit possible de t'apporter l'aide dont tu as besoin.
Je comprends bien. Moi si je devais faire de la biologie, qu'est-ce que ça donnerait hein ? ;)
Bien sûr que si que ça va ralentir. Mais est-ce vraiment un problème ?
Si j'en crois le volume de données que tu traites, le temps d'écriture/manipulation des fichiers ne représente pas grand chose. Mais il y a un avantage à utiliser les fichiers: tu gardes une trace de ce qui a été lu. Et tu peux vérifier manuellement que les données ont bien été transmises comme il faut. Pour cela, au moins dans le temps de la mise au point du code, je ferai une capture des données dans des fichiers :)
Les informaticiens disent qu'une optimisation prématurée c'est la source de gros problèmes. Tu ne devrais pas au moins dans un premier temps, te poser la question de la rapidité d'exécution. Tu me dirais sur la routine qui analyse les données, je dirais peut être qu'il faut s'en soucier, mais il n'y a pas à se soucier de quelques entrées/sorties supplémentaires dans ton cas.
J'ai regardé ton code plus attentivement. Sous réserve que les classes PostMethod et HttpClient ne soient pas bugguées, ce code doit marcher il me semble (Mais pourquoi diable ne pas utiliser HttpURLConnection de la jdk ?)
Maintenant si le code marche sur ta machine de test il marche.
S'il ne marche pas de la façon que tu décris sur une autre machine, il y a peut être un problème de hardware réseau. Par exemple une mésentente entre une carte réseau intégrée et un routeur. Ca s'est déjà vu. Et d'une certaine façon ce que tu dis peut en être un symptome. Pour ce que tu fais, il n'y a pas de différence en XP et XP pro. A ta place j'essaierai d'enquêter du côté du matériel.
Oui, c'est ce que je me dis aussi, je suis en train de regarder du côté du matériel.
En fait, si je n'utilise pas HttpURLConnection, c'est tout simplement que je ne connaissais pas cette classe! Dans le code que j'ai ré-utilisé, le gars avait utilisé HttpClient, donc je m'en suis inspiré pour écrire ma méthode.
Oui si j'avais pu! Je ne l'ai appris que quelques minutes avant de lancer le programme. En fait, j'ai fait la modif que j'ai postée, j'ai testé sur mon PC, c'était OK. J'ai donc voulu lancer l'analyse complète sur l'autre PC, et là ça bloque, toujours à l'endroit qui ne posait plus de problème après la modification.
Oui, je peux comprendre. Je me disais juste que tu m'avais filé 2 solutions utilisables, une qui me plaisait plus mais qui bloquait à la fameuse 7ème requête, et une qui marchait nickel mais que je trouvais moins pratique à manipuler par rapport à la suite du programme. Je me suis dit qu'au lieu de tout de suite appeler à l'aide tu préfererai que je m'investisse un peu et cherche par moi-même.
Bon, je regarde le matériel.
Merci
Julien