How to test and update your plugin for XNAT 1.8.6 compatibility
Identifying Plugins with a Jackson Dependency
If you are unsure whether any of your installed plugins has a Jackson dependency that will be affected by this upgrade, try running the following from within your XNAT's plugins folder:
for JAR in *.jar; do
[[ $(jar tf ${JAR} | grep -E ‘com[-/.]fasterxml[-/.]jackson' | wc -l | tr -d ' ') -gt 0 ]] && { echo "${JAR}"; }
done
If you have any matching plugins, you can either look for a newer released version or follow the instructions below.
Issues caused by upgrading Jackson from 2.6.5 to 2.13.3
If you have a custom plugin that has API methods with an om
class as a @RequestBody
param or as the @ResponseBody
return type, you will need to update your plugin as noted below.
Change your parameters/return types from the
om
class to the auto-generated interface for that class. In the example below we would changeMlTrainconfig
toMlTrainconfigI
.Original Code
JAVA@XapiRequestMapping(consumes = {APPLICATION_JSON_VALUE, APPLICATION_XML_VALUE}, produces = {APPLICATION_JSON_VALUE, APPLICATION_XML_VALUE}, method = POST) @ResponseBody public MlTrainconfig createTrainingConfiguration(final @RequestBody MlTrainconfig configuration) throws ResourceAlreadyExistsException, DataFormatException {
Updated Code
JAVA@XapiRequestMapping(consumes = {APPLICATION_JSON_VALUE, APPLICATION_XML_VALUE}, produces = {APPLICATION_JSON_VALUE, APPLICATION_XML_VALUE}, method = POST) @ResponseBody public MlTrainconfigI createTrainingConfiguration(final @RequestBody MlTrainconfigI configuration) throws ResourceAlreadyExistsException, DataFormatException {
Tell Jackson which class to instantiate when it tries to deserialize your interface. To do that, you will need to configure a
com.fasterxml.jackson.databind.Module
bean to map the interface to theom
class. This bean definition can be placed in any class annotated with@XnatPlugin
or@Configuration
.JAVA@XnatPlugin(value = "datasetsPlugin", name = "XNAT Datasets Plugin", logConfigurationFile = "datasets-logback.xml", dataModels = {@XnatDataModel(value = SetsDefinition.SCHEMA_ELEMENT_NAME, singular = "Dataset Definition", plural = "Dataset Definitions"), @XnatDataModel(value = SetsCollection.SCHEMA_ELEMENT_NAME, singular = "Dataset Collection", plural = "Dataset Collections")})) @ComponentScan({"org.nrg.xnatx.plugins.datasets.converters", "org.nrg.xnatx.plugins.datasets.resolvers", "org.nrg.xnatx.plugins.datasets.rest", "org.nrg.xnatx.plugins.datasets.services.impl"}) public class XnatDatasetsPlugin { @Bean public Module xnatMlModule() { final SimpleModule module = new SimpleModule(); final SimpleAbstractTypeResolver resolver = new SimpleAbstractTypeResolver(); resolver.addMapping(MlTrainconfigI.class, MlTrainconfig.class); module.setAbstractTypes(resolver); return module; } }
Add explicit type casts to convert your interface back into the
om
class (or update your service layer code to pass around the interface)JAVAMlTrainconfig mlTrainconfig = (MlTrainconfig) configuration;