Ho bisogno di hot-deploy e -undeploy risorse in un ServletContainer Jersey.Dinamicamente (un) distribuzione di risorse in Jersey
Sembra non esserci modo di "annullare la registrazione" delle risorse su un ResourceConfig, quindi il percorso che sto seguendo è quello di sostituire tutte le risorse con un nuovo set.
Anche se the documentation dice registerResources on ResourceConfig sostituisce tutte le risorse, sfogliare il codice sorgente sembra contraddire questo.
La soluzione che ho trovato era di ricaricare ServletContainer con un ResourceConfig completamente nuovo.
Set<Class<?>> classes = ...
ResourceConfig config = new ResourceConfig(classes);
container.reload(config);
Questo funziona fino a quando non distribuisco una risorsa che risulta in ModelValidationException. Dopodiché non riesco a riportare ServletContainer in uno stato corretto.
Se prendo uno sguardo al codice sorgente:
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);
}
}
Il ModelValidationException è gettato dal costruttore WebComponent. Successivamente, qualsiasi chiamata a ricaricare genera un'eccezione dal metodo onShutdown, causato da checkState nel metodo preDestroy di ServiceLocatorImpl.
posso evitare l'eccezione ignorando gli errori di convalida
ResourceConfig config = new ResourceConfig(classes);
config.property(ServerProperties.RESOURCE_VALIDATION_IGNORE_ERRORS,
Boolean.TRUE);
container.reload(config);
Non c'è modo ora però per scoprire se ci sono stati errori, ma per esplorare la registrazione, che è altrettanto male, davvero.
Per heenenee's comment Ho provato la sottoclasse di ServletContainer, ma qualcosa di simile dà problemi in quanto il ResourceConfig non può essere inserito in due WebComponents.
Ho cercato di creare il WebComponent prima di spegnersi, per ottenere una rapida uscita, ma questo viene a mancare la ricarica effettiva se non ci sono errori nelle risorse (perché il ResourceConfig non può essere modificato dopo che il webcomponent è stata creata)
@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);
}
C'è un altro modo per hot-undeploy delle risorse? C'è un modo per resettare ServletContainer dopo un errore di ricarica?
Si potrebbe provare a creare una sottoclasse 'ServletContainer', override' reload (ResourceConfig) '' per la cattura RuntimeException' e registrare un errore, quindi specificare la sottoclasse in web.xml. – heenenee