我需要在 Jersey ServletContainer 中热部署和取消部署资源。
似乎没有办法在 ResourceConfig 上“取消注册”资源,所以我遵循的路线是用新集合替换所有资源。
虽然the documentation说 ResourceConfig 上的 registerResources 替换了所有资源,浏览源代码似乎与此相矛盾。
我找到的解决方案是使用全新的 ResourceConfig 重新加载 ServletContainer。
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 构造函数中抛出的。 之后,任何对 reload 的调用都会导致 onShutdown 方法出现异常,这是由 ServiceLocatorImpl 的 preDestroy 方法中的 checkState 引起的。
我可以通过忽略验证错误来避免异常
ResourceConfig config = new ResourceConfig(classes);
config.property(ServerProperties.RESOURCE_VALIDATION_IGNORE_ERRORS,
Boolean.TRUE);
container.reload(config);
但是,现在除了探索日志记录之外,没有办法查明是否有任何错误,这同样糟糕,真的。
根据 heenenee's comment我尝试将 ServletContainer 子类化,但这样的事情会产生问题,因为 ResourceConfig 不能放在两个 WebComponents 中。
我尝试在关闭之前创建 WebComponent,以便提前退出,但是如果资源中没有错误,则实际重新加载失败(因为在创建 Web 组件后无法修改资源配置)
@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);
}
还有其他方法可以热取消部署资源吗?有没有办法在重新加载失败后重置 ServletContainer?
最佳答案
我认为如果不使用支持热部署的 servlet 容器,这是无法实现的。以我的经验,这样做的一个好方法是使用支持 OSGi 的容器。你可以看看Eclipse Virgo或 Apache Karaf .
例如,在 OSGi 环境中,您可以创建模块(称为 bundle ),这些模块可以拖放到扫描的文件夹中以在运行时启用功能,或从文件夹中删除以禁用某些功能。这类似于插件在 Eclipse IDE 中的工作方式,其中新插件安装/卸载不一定需要重新启动。
关于java - 在 Jersey 动态(取消)部署资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33940935/