2010-08-19 5 views
0

J'utilise com.sun.net.httpserver.HttpServer dans mon projet. Cependant, il semble que le serveur fuit les connexions lorsqu'il reçoit des données invalides de la connexion HTTP. Le bug est celui-ci:Sun Java HTTPServer a un bug, comment y remédier?

http://bugs.sun.com/view_bug.do;jsessionid=dfe841c3152d878571573bafceb8?bug_id=6946825

Maintenant, cela devrait être résolu dans la version « 7 (B94) » - cependant, nous utilisons encore Java 1.6 et il est peu probable que nous voulons commutateur Java versions à ce stade. Donc, je cherche des façons de résoudre cette situation. Je n'ai pas beaucoup de temps, donc je préfère des solutions rapides qui fonctionnent pour le moment, plutôt que de réimplémenter beaucoup de choses pour plus tard.

J'ai quelques idées sur la façon d'aller à ce sujet:

  • Mise à jour une version plus récente de Java - c'est quelque chose que je ne veux pas faire.
  • Recherchez un fichier jar contenant uniquement une version plus récente de com.sun.net.httpserver et assurez-vous que le fichier jar est chargé avant les fichiers système.
  • Trouver un remplaçant pour com.sun.net.httpserver - Je suis ouvert aux pointeurs ici.
  • Modifiez le code pour qu'il fonctionne avec un autre serveur HTTP intégré, avec un peu de chance, un peu différent de l'actuel. Je peux réécrire le code de configuration du serveur, mais la plupart des interfaces devraient rester les mêmes.
  • décompiler la classe com.sun.net.httpserver.ServerImpl, fixer les lieux incriminés, et recompiler cette classe unique à un pot de son propre

Mais, je suis ouvert à de bonnes suggestions!

Merci d'avance.


Le correctif est maintenant implémenté et fonctionne. Je vais coller ici les bits pertinents si quelqu'un d'autre a besoin de ces:

final Field httpserverimpl_server = Class.forName("sun.net.httpserver.HttpServerImpl").getDeclaredField("server"); 
final Field httpsserverimpl_server = Class.forName("sun.net.httpserver.HttpsServerImpl").getDeclaredField("server"); 
final Field serverimpl_allconnections = Class.forName("sun.net.httpserver.ServerImpl").getDeclaredField("allConnections"); 
final Field httpconnection_closed = Class.forName("sun.net.httpserver.HttpConnection").getDeclaredField("closed"); 

httpserverimpl_server.setAccessible(true); 
httpsserverimpl_server.setAccessible(true); 
serverimpl_allconnections.setAccessible(true); 
httpconnection_closed.setAccessible(true); 

Object serverimpl = httpserverimpl_server.get(server); 
Set allconnections = (Set)serverimpl_allconnections.get(serverimpl); 
LinkedList<Object> toRemove = new LinkedList<Object>(); 
for (Object conn : allconnections) { 
    if (httpconnection_closed.getBoolean(conn)) { 
     toRemove.add(conn); 
    } 
} 
for (Object conn : toRemove) { 
    allconnections.remove(conn); 
} 
+0

trouvé le changeset de fixation ainsi: http://hg.openjdk.java.net/jdk7/jdk7/jdk/rev/0bda20126372 – Nakedible

Répondre

2

Je comprends votre réticence à passer à une version pré-version de Java 7.

Voici mes suggestions:

  • Obtenir un contrat de support Java d'Oracle et les amener à vous fournir avec un patch pour Java 6 qui corrige le bug.Téléchargez les sources Java 6 pour la version que vous utilisez actuellement, rétroportez le correctif de bogue des sources et de la compilation Java 7. Peut-être que vous avez seulement besoin de faire une compilation de certains fichiers JAR. Regardez le code et voyez si vous pouvez développer une solution de contournement. Par exemple, vous pouvez utiliser la réflexion pour extraire la «liste des instances HttpConnection» dont parle le rapport de bogue et supprimer périodiquement les entrées qui semblent être mortes. (Je traite cela comme un dernier recours.)


(Mise à jour: 2012-05-15)

Et, maintenant que Java 7 est bel et bien sorti (nous sommes maintenant à 1.7u4):

  • mise à niveau vers Java 7 et

  • se débarrasser des méchants hacks réfléchissants que vous avez utilisé comme workaro TEMPORAIRE und.

+0

J'ai réussi à cuire une classe qui utilise la réflexion pour déterrer l'instance ServerImpl, passe par son ensemble allConnections et utilise à nouveau la réflexion pour vérifier si HttpConnection est fermé - si c'est le cas, il est retiré de l'ensemble N'a pas été capable de l'essayer dans le code actuel pour voir si cela résout le problème, mais cela semble possible au moins en théorie. – Nakedible

+0

Cool. Si j'étais vous, je lirais attentivement le code source et essayerais de vous convaincre que votre approche devrait l'être. Aussi, laissez-vous et les futurs responsables un gros rappel pour se débarrasser de la solution de contournement lorsque vous effectuez une mise à niveau vers Java 7. –

+0

La réflexion est - et BIG REMINDERs sont en place. De plus, le code est protégé dans les blocs try de sorte que si cela ne fonctionne pas, il avertit et n'essaie pas de nettoyer les connexions pour que le code fonctionne automatiquement sur les plateformes où le serveur https est différent et ne partage pas les mêmes bogues. – Nakedible

0

Avez-vous accès à 7 (B94)? Ensuite, vous pouvez comparer les sources et voir si vous pouvez le réparer en remplaçant ou en fournissant différents accesseurs.

+0

J'ai accès à la version - il semble que je peux enregistrer un autre HttpServerProvider , par exemple, c'est donc remplaçable, mais je ne suis toujours pas sûr de la solution la plus simple. – Nakedible

2

Pourriez-vous mettre un proxy inverse en face du serveur HTTP, pour vous assurer que vous autorisez uniquement les demandes connues connues à passer? Vernis ou Calmar ou Apache?

Ou de taper quelque chose dans Jetty afin qu'il agisse comme un proxy inverse?

Une autre approche serait de saisir la source code de la version corrigée, de renommer la classe et le package de manière à ce qu'elle s'intègre dans votre projet, rendre la classe publique, puis utiliser cette implémentation à la place.

+0

Compliquer la configuration est encore pire à ce stade - c'est un environnement très strict. Bonne idée, cependant! – Nakedible

+0

+1 Cela me semble vraiment plus propre, plus simple et plus sûr que la réponse acceptée. – user359996

Questions connexes