В Sun Java HTTPServer есть ошибка, как ее исправить?
-
29-09-2019 - |
Вопрос
Я использую 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)? Затем вы можете сравнить источники и посмотреть, сможете ли вы исправить его, переопределение или предоставление различных доступа.