2009-07-02 10 views
0

J'écris une applet Java qui télécharge des images à partir d'un serveur Web et les affiche à l'utilisateur. Il fonctionne très bien dans Java 1.6.0_3 et versions ultérieures, mais sur les versions plus anciennes, il plante complètement le processus environ toutes les 20 pages vues. Il n'y a pas de messages d'erreur dans la console Java, car le processus est complètement gelé. J'ai attendu parfois 15 minutes, mais ça ne gèle jamais.Java URLConnection bloque le processus entier lorsque j'appelle getInputStream

J'ai ajouté un message de débogage après chaque ligne de code, et déterminé que la ligne qui provoque le plantage est la suivante: InputStream data = urlConn.getInputStream(). UrlConn est un objet URLConnection pointé sur l'image que je veux charger.

J'ai essayé toutes les combinaisons d'options auxquelles je peux penser, mais rien n'y fait. Je n'ai pas réussi à trouver quoi que ce soit dans la base de données de bogues Java ou dans les notes de version de la version 1.6.0_3.

Quelqu'un at-il déjà rencontré ce problème? Toute idée de comment résoudre ce problème?

+0

Il pourrait être intéressant de capturer le trafic réseau vers et à partir de cette applet en utilisant Wireshark, juste pour voir où les choses se raccrochent. –

+0

Quel type d'URLConnection utilisez-vous? Cela peut faire la différence si vous basculez l'implémentation que vous utilisez car la méthode getInputStream() n'est pas implémentée dans la classe de base URLConnection. –

Répondre

1

Pour déterminer si elle est vraiment l'ensemble du processus de machine virtuelle Java qui est gelé, ou quelque chose d'autre:

(1) obtenir un vidage de la pile java (sigquit/ctrl-break/jstack)

(2) ont un autre fil de fond faisant quelque chose que vous pouvez observer; ça arrête? (3) vérifier si un autre processus (navigateur/etc) peut contacter le serveur pendant le gel? (Il y a une chance que le vrai problème soit l'épuisement de la connexion du serveur)

Est-ce une fois par 20 fois aléatoire (par exemple, 5% du temps, parfois la première fetch de la JVM), ou toujours après environ 20 fetchs? Si ce dernier, il semble que quelque chose ne soit pas fermé correctement. Si vous utilisez Linux, vous pouvez utiliser 'netstat -t' ou 'lsof' (avec certaines options ou grepped pour n'afficher que quelques lignes) pour voir les sockets ouverts; si après chaque extraction, une autre est ouverte et que le compte ne descend jamais, vous ne fermez pas les choses correctement. Si oui, appeler close() sur le flux que vous obtenez et/ou déconnecter() sur HttpUrlConnection après chaque essai peut aider. (Il peut également y avoir des limites plus sévères sur le nombre de connexions qu'un applet peut laisser ouvert, donc vous frappez ceci plus rapidement que vous le feriez dans une application autonome.)

Le fait que cela fonctionne dans Javas plus tard est également suggestive qu'une sorte de nettoyage automatique pourrait se produire plus efficacement/régulièrement par la finalisation/GC. Il est préférable de fermer vous-même les choses proprement mais vous pouvez aussi essayer de forcer une GC/runFinalization dans les Javas plus tôt montrant le problème.

+0

J'ai essayé # 2 tout à l'heure, et chaque fil gelait en même temps. Il s'agit d'un nombre aléatoire de 5% de pages vues - parfois, cela arrive la première fois que l'applet est chargée. J'ai oublié de fermer le flux de données, ce qui aurait pu être le problème. Mais quand j'ai ajouté du code pour le faire, cela n'a pas résolu le problème. Donc, je suis toujours coincé. –

0

Je ne suis pas sûr la cause du problème que vous rencontrez, mais j'utiliser le code suivant pour le chargement de manière synchrone avec succès des images de l'intérieur applets (charges de non jar ou le serveur):

public Image loadImage(String imageName) { 

    // get the image 
    Image image = getImage(getCodeBase(), imageName); 

    // wait for it to fully load 
    MediaTracker tracker = new MediaTracker(this); 
    tracker.addImage(image, 0); 
    boolean interrupted = false; 
    try { 
     tracker.waitForID(0); 
    } catch (InterruptedException e) { 
     interrupted = true; 
    } 

    int status = tracker.statusID(thisImageTrackerID, false); 
    if (status != MediaTracker.COMPLETE) { 
     throw new RuntimeException("Failed to load " + imageName + ", interrupted:" + interrupted + ", status:" + status); 
    } 

    return image; 
} 
Questions connexes