Мне нужно развернуть и -undeploy ресурсы в сервисе ServletContainer.
Кажется, что нет способа "отменить регистрацию" ресурсов в ResourceConfig, поэтому следующий маршрут - это замена всех ресурсов новым набором.
Хотя документация говорит, что registerResources на ResourceConfig заменяет все ресурсы, просмотр исходного кода, похоже, противоречит этому.
Решение, которое я нашел, это перезагрузить ServletContainer с полностью новым ResourceConfig.
Set<Class<?>> classes = ...
ResourceConfig config = new ResourceConfig(classes);
container.reload(config);
Это отлично работает, пока я не развожу ресурс, из-за которого возникает исключение ModelValidationException. После этого я не могу вернуть ServletContainer в правильное состояние.
Если я взгляну на исходный код:
public void reload(final ResourceConfig configuration) {
try {
containerListener.onShutdown(this);
webComponent = new WebComponent(webComponent.webConfig, configuration);
containerListener = webComponent.appHandler;
containerListener.onReload(this);
containerListener.onStartup(this);
} catch (final ServletException ex) {
LOGGER.log(Level.SEVERE, "Reload failed", ex);
}
}
Отличие ModelValidationException от конструктора WebComponent. После этого любой вызов для перезагрузки приводит к исключению из метода onShutdown, вызванного checkState в методе preDestroy ServiceLocatorImpl.
Я могу избежать исключения, игнорируя ошибки проверки
ResourceConfig config = new ResourceConfig(classes);
config.property(ServerProperties.RESOURCE_VALIDATION_IGNORE_ERRORS,
Boolean.TRUE);
container.reload(config);
Теперь нет никакого способа узнать, были ли какие-либо ошибки, но чтобы исследовать журнал, который так же плох, действительно.
Per комментарий heenenee Я попробовал подкласс SerletContainer, но что-то вроде этого дает проблемы, потому что ResourceConfig нельзя поместить в два WebComponents.
Я попытался создать WebComponent перед завершением работы, чтобы получить ранний выход, но это не позволяет выполнить реальную перезагрузку, если в ресурсах нет ошибки (поскольку ресурсconfig не может быть изменен после создания веб-компонента)
@Override
public void reload(ResourceConfig configuration) {
try {
new WebComponent(new WebServletConfig(this), configuration);
} catch (ServletException e) {
LOGGER.log(Level.SEVERE, "Reload failed", e);
List<ResourceModelIssue> resources = Collections.emptyList();
throw new ModelValidationException(e.getMessage(), resources);
}
super.reload(configuration);
}
Есть ли другой способ для горячего undeploy ресурсов? Есть ли способ reset ServletContainer после неудачной перезагрузки?