Вопрос

Я использую com.sun.net.httpserver.HttpServer в своем проекте.Однако похоже, что сервер теряет соединения, когда получает неверные данные из HTTP-соединения.Баг вот этот:

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

Сообщается, что это исправлено в версии «7(b94)», однако мы все еще используем Java 1.6, и маловероятно, что на этом этапе нам захочется переключать версии Java.

Поэтому я ищу способы исправить эту ситуацию.У меня мало времени, поэтому я предпочитаю быстрые решения, которые работают сейчас, а не переделывать многие вещи на будущее.

У меня есть несколько идей, как это сделать:

  • Обновление до более новой версии Java - я не хочу этого делать.
  • Найдите jar, который содержит только более свежую версию com.sun.net.httpserver, и убедитесь, что jar загружается до того, как будет загружена система.
  • Найдите замену com.sun.net.httpserver — я открыт для указателей здесь.
  • Измените код для работы с другим встроенным HTTP-сервером, надеюсь, не слишком отличающимся от текущего.Я могу немного переписать код настройки сервера, но большинство интерфейсов должно остаться прежним.
  • Декомпилируйте класс com.sun.net.httpserver.ServerImpl, исправьте проблемные места и перекомпилируйте этот единственный класс в собственный jar-файл.

Но я открыт для хороших предложений!

Заранее спасибо.


Исправление теперь реализовано и работает.Я вставлю сюда соответствующие фрагменты, если они кому-то еще понадобятся:

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);
}
Это было полезно?

Решение

Я понимаю ваше нежелание переходить на предварительную сборку Java 7.

Вот мои предложения:

  • Получите контракт на поддержку Java от Oracle и попросите их предоставить вам патч для Java 6, исправляющий ошибку.

  • Загрузите исходные коды Java 6 для используемой в данный момент версии, скопируйте исправление ошибки из исходных кодов Java 7 и выполните сборку.Возможно, вам нужно выполнить сборку только определенных файлов JAR.

  • Посмотрите на код и попробуйте найти обходной путь.Например, вы можете использовать отражение, чтобы найти «список экземпляров HttpConnection», о котором говорится в отчете об ошибке, и периодически удалять записи, которые выглядят так, как будто они мертвы.(Я бы отнесся к этому как к последнему средству.)


(Обновлено:15 мая 2012 г.)

И теперь, когда Java 7 полностью выпущена (сейчас мы находимся на версии 1.7u4):

  • обновиться до Java 7 и

  • избавьтесь от неприятных рефлексивных приемов, которые вы использовали в качестве ВРЕМЕННОГО обходного пути.

Другие советы

Не могли бы вы установить обратный прокси-сервер перед HTTP-сервером, чтобы гарантировать, что вы пропускаете только заведомо хорошие запросы?Лак или Кальмар или Апач?

Или наколотить что-нибудь Пристань чтобы он действовал как обратный прокси?

Другой подход заключается в том, чтобы захватить исходный код фиксированной версии, переименуйте класс и пакет, чтобы они вписывались в ваш проект, сделайте класс общедоступным, а затем используйте вместо него эту реализацию.

У вас есть доступ к 7 (B94)? Затем вы можете сравнить источники и посмотреть, сможете ли вы исправить его, переопределение или предоставление различных доступа.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top