From 1e501f2583efd7521fe457453e5f866bcb8c509a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deleuze?= Date: Fri, 19 Jun 2020 08:54:21 +0200 Subject: [PATCH] Provide a flag to disable XML support This commit introduces a spring.xml.ignore system property which when set to true avoid initializing XML infrastructure. A typical use case is optimizing GraalVM native image footprint for applications not using XML. In order to be effective, those classes should be initialized at build time: - org.springframework.util.DefaultPropertiesPersister - org.springframework.core.io.support.PropertiesLoaderUtils - org.springframework.web.servlet.function.support.RouterFunctionMapping - org.springframework.web.client.RestTemplate - org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport - org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter - org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter - org.springframework.http.codec.support.BaseDefaultCodecs - org.springframework.beans.PropertyEditorRegistrySupport Closes gh-25151 --- .../beans/PropertyEditorRegistrySupport.java | 16 +++++++- .../io/support/PropertiesLoaderUtils.java | 18 +++++++++ .../util/DefaultPropertiesPersister.java | 22 +++++++++- .../http/codec/support/BaseDefaultCodecs.java | 14 +++++-- ...lEncompassingFormHttpMessageConverter.java | 31 +++++++++----- .../web/client/RestTemplate.java | 33 ++++++++++----- .../WebMvcConfigurationSupport.java | 40 ++++++++++++------- .../support/RouterFunctionMapping.java | 22 +++++++--- .../ExceptionHandlerExceptionResolver.java | 22 +++++++--- .../RequestMappingHandlerAdapter.java | 21 +++++++--- 10 files changed, 184 insertions(+), 55 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/PropertyEditorRegistrySupport.java b/spring-beans/src/main/java/org/springframework/beans/PropertyEditorRegistrySupport.java index e73a34fb7f..f18be1bb7f 100644 --- a/spring-beans/src/main/java/org/springframework/beans/PropertyEditorRegistrySupport.java +++ b/spring-beans/src/main/java/org/springframework/beans/PropertyEditorRegistrySupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -71,6 +71,7 @@ import org.springframework.beans.propertyeditors.URIEditor; import org.springframework.beans.propertyeditors.URLEditor; import org.springframework.beans.propertyeditors.UUIDEditor; import org.springframework.beans.propertyeditors.ZoneIdEditor; +import org.springframework.core.SpringProperties; import org.springframework.core.convert.ConversionService; import org.springframework.core.io.Resource; import org.springframework.core.io.support.ResourceArrayPropertyEditor; @@ -84,6 +85,7 @@ import org.springframework.util.ClassUtils; * * @author Juergen Hoeller * @author Rob Harrop + * @author Sebastien Deleuze * @since 1.2.6 * @see java.beans.PropertyEditorManager * @see java.beans.PropertyEditorSupport#setAsText @@ -91,6 +93,14 @@ import org.springframework.util.ClassUtils; */ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry { + /** + * Boolean flag controlled by a {@code spring.xml.ignore} system property that instructs Spring to + * ignore XML, i.e. to not initialize the XML-related infrastructure. + *

The default is "false". + */ + private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore"); + + @Nullable private ConversionService conversionService; @@ -208,7 +218,9 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry { this.defaultEditors.put(Currency.class, new CurrencyEditor()); this.defaultEditors.put(File.class, new FileEditor()); this.defaultEditors.put(InputStream.class, new InputStreamEditor()); - this.defaultEditors.put(InputSource.class, new InputSourceEditor()); + if (!shouldIgnoreXml) { + this.defaultEditors.put(InputSource.class, new InputSourceEditor()); + } this.defaultEditors.put(Locale.class, new LocaleEditor()); this.defaultEditors.put(Path.class, new PathEditor()); this.defaultEditors.put(Pattern.class, new PatternEditor()); diff --git a/spring-core/src/main/java/org/springframework/core/io/support/PropertiesLoaderUtils.java b/spring-core/src/main/java/org/springframework/core/io/support/PropertiesLoaderUtils.java index 6efa78f3da..6fff4b0bc8 100644 --- a/spring-core/src/main/java/org/springframework/core/io/support/PropertiesLoaderUtils.java +++ b/spring-core/src/main/java/org/springframework/core/io/support/PropertiesLoaderUtils.java @@ -24,6 +24,7 @@ import java.net.URLConnection; import java.util.Enumeration; import java.util.Properties; +import org.springframework.core.SpringProperties; import org.springframework.core.io.Resource; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -41,6 +42,7 @@ import org.springframework.util.ResourceUtils; * * @author Juergen Hoeller * @author Rob Harrop + * @author Sebastien Deleuze * @since 2.0 * @see PropertiesLoaderSupport */ @@ -48,6 +50,13 @@ public abstract class PropertiesLoaderUtils { private static final String XML_FILE_EXTENSION = ".xml"; + /** + * Boolean flag controlled by a {@code spring.xml.ignore} system property that instructs Spring to + * ignore XML, i.e. to not initialize the XML-related infrastructure. + *

The default is "false". + */ + private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore"); + /** * Load properties from the given EncodedResource, @@ -88,6 +97,9 @@ public abstract class PropertiesLoaderUtils { try { String filename = resource.getResource().getFilename(); if (filename != null && filename.endsWith(XML_FILE_EXTENSION)) { + if (shouldIgnoreXml) { + throw new UnsupportedOperationException("XML support disabled"); + } stream = resource.getInputStream(); persister.loadFromXml(props, stream); } @@ -133,6 +145,9 @@ public abstract class PropertiesLoaderUtils { try (InputStream is = resource.getInputStream()) { String filename = resource.getFilename(); if (filename != null && filename.endsWith(XML_FILE_EXTENSION)) { + if (shouldIgnoreXml) { + throw new UnsupportedOperationException("XML support disabled"); + } props.loadFromXML(is); } else { @@ -180,6 +195,9 @@ public abstract class PropertiesLoaderUtils { ResourceUtils.useCachesIfNecessary(con); try (InputStream is = con.getInputStream()) { if (resourceName.endsWith(XML_FILE_EXTENSION)) { + if (shouldIgnoreXml) { + throw new UnsupportedOperationException("XML support disabled"); + } props.loadFromXML(is); } else { diff --git a/spring-core/src/main/java/org/springframework/util/DefaultPropertiesPersister.java b/spring-core/src/main/java/org/springframework/util/DefaultPropertiesPersister.java index 4e5cd51169..b5e452a992 100644 --- a/spring-core/src/main/java/org/springframework/util/DefaultPropertiesPersister.java +++ b/spring-core/src/main/java/org/springframework/util/DefaultPropertiesPersister.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,8 @@ import java.io.Reader; import java.io.Writer; import java.util.Properties; +import org.springframework.core.SpringProperties; + /** * Default implementation of the {@link PropertiesPersister} interface. * Follows the native parsing of {@code java.util.Properties}. @@ -46,6 +48,7 @@ import java.util.Properties; * "defaultEncoding" and "fileEncodings" properties). * * @author Juergen Hoeller + * @author Sebastien Deleuze * @since 10.03.2004 * @see java.util.Properties * @see java.util.Properties#load @@ -53,6 +56,14 @@ import java.util.Properties; */ public class DefaultPropertiesPersister implements PropertiesPersister { + /** + * Boolean flag controlled by a {@code spring.xml.ignore} system property that instructs Spring to + * ignore XML, i.e. to not initialize the XML-related infrastructure. + *

The default is "false". + */ + private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore"); + + @Override public void load(Properties props, InputStream is) throws IOException { props.load(is); @@ -75,16 +86,25 @@ public class DefaultPropertiesPersister implements PropertiesPersister { @Override public void loadFromXml(Properties props, InputStream is) throws IOException { + if (shouldIgnoreXml) { + throw new UnsupportedOperationException("XML support disabled"); + } props.loadFromXML(is); } @Override public void storeToXml(Properties props, OutputStream os, String header) throws IOException { + if (shouldIgnoreXml) { + throw new UnsupportedOperationException("XML support disabled"); + } props.storeToXML(os, header); } @Override public void storeToXml(Properties props, OutputStream os, String header, String encoding) throws IOException { + if (shouldIgnoreXml) { + throw new UnsupportedOperationException("XML support disabled"); + } props.storeToXML(os, header, encoding); } diff --git a/spring-web/src/main/java/org/springframework/http/codec/support/BaseDefaultCodecs.java b/spring-web/src/main/java/org/springframework/http/codec/support/BaseDefaultCodecs.java index fe77131905..779c88c850 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/support/BaseDefaultCodecs.java +++ b/spring-web/src/main/java/org/springframework/http/codec/support/BaseDefaultCodecs.java @@ -21,6 +21,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import org.springframework.core.SpringProperties; import org.springframework.core.codec.AbstractDataBufferDecoder; import org.springframework.core.codec.ByteArrayDecoder; import org.springframework.core.codec.ByteArrayEncoder; @@ -70,6 +71,13 @@ import org.springframework.util.ClassUtils; */ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigurer.DefaultCodecConfig { + /** + * Boolean flag controlled by a {@code spring.xml.ignore} system property that instructs Spring to + * ignore XML, i.e. to not initialize the XML-related infrastructure. + *

The default is "false". + */ + private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore"); + static final boolean jackson2Present; private static final boolean jackson2SmilePresent; @@ -284,7 +292,7 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure ((AbstractJackson2Decoder) codec).setMaxInMemorySize(size); } } - if (jaxb2Present) { + if (jaxb2Present && !shouldIgnoreXml) { if (codec instanceof Jaxb2XmlDecoder) { ((Jaxb2XmlDecoder) codec).setMaxInMemorySize(size); } @@ -353,7 +361,7 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure addCodec(readers, new DecoderHttpMessageReader<>(this.jackson2SmileDecoder != null ? (Jackson2SmileDecoder) this.jackson2SmileDecoder : new Jackson2SmileDecoder())); } - if (jaxb2Present) { + if (jaxb2Present && !shouldIgnoreXml) { addCodec(readers, new DecoderHttpMessageReader<>(this.jaxb2Decoder != null ? (Jaxb2XmlDecoder) this.jaxb2Decoder : new Jaxb2XmlDecoder())); } @@ -449,7 +457,7 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure writers.add(new EncoderHttpMessageWriter<>(this.jackson2SmileEncoder != null ? (Jackson2SmileEncoder) this.jackson2SmileEncoder : new Jackson2SmileEncoder())); } - if (jaxb2Present) { + if (jaxb2Present && !shouldIgnoreXml) { writers.add(new EncoderHttpMessageWriter<>(this.jaxb2Encoder != null ? (Jaxb2XmlEncoder) this.jaxb2Encoder : new Jaxb2XmlEncoder())); } diff --git a/spring-web/src/main/java/org/springframework/http/converter/support/AllEncompassingFormHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/support/AllEncompassingFormHttpMessageConverter.java index ee7d13f2e1..d747800c46 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/support/AllEncompassingFormHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/support/AllEncompassingFormHttpMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.springframework.http.converter.support; +import org.springframework.core.SpringProperties; import org.springframework.http.converter.FormHttpMessageConverter; import org.springframework.http.converter.json.GsonHttpMessageConverter; import org.springframework.http.converter.json.JsonbHttpMessageConverter; @@ -32,10 +33,18 @@ import org.springframework.util.ClassUtils; * * @author Rossen Stoyanchev * @author Juergen Hoeller + * @author Sebastien Deleuze * @since 3.2 */ public class AllEncompassingFormHttpMessageConverter extends FormHttpMessageConverter { + /** + * Boolean flag controlled by a {@code spring.xml.ignore} system property that instructs Spring to + * ignore XML, i.e. to not initialize the XML-related infrastructure. + *

The default is "false". + */ + private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore"); + private static final boolean jaxb2Present; private static final boolean jackson2Present; @@ -61,15 +70,17 @@ public class AllEncompassingFormHttpMessageConverter extends FormHttpMessageConv public AllEncompassingFormHttpMessageConverter() { - try { - addPartConverter(new SourceHttpMessageConverter<>()); - } - catch (Error err) { - // Ignore when no TransformerFactory implementation is available - } + if (!shouldIgnoreXml) { + try { + addPartConverter(new SourceHttpMessageConverter<>()); + } + catch (Error err) { + // Ignore when no TransformerFactory implementation is available + } - if (jaxb2Present && !jackson2XmlPresent) { - addPartConverter(new Jaxb2RootElementHttpMessageConverter()); + if (jaxb2Present) { + addPartConverter(new Jaxb2RootElementHttpMessageConverter()); + } } if (jackson2Present) { @@ -82,7 +93,7 @@ public class AllEncompassingFormHttpMessageConverter extends FormHttpMessageConv addPartConverter(new JsonbHttpMessageConverter()); } - if (jackson2XmlPresent) { + if (jackson2XmlPresent && !shouldIgnoreXml) { addPartConverter(new MappingJackson2XmlHttpMessageConverter()); } diff --git a/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java b/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java index 8e058bfca0..84870ca1a2 100644 --- a/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java +++ b/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java @@ -29,6 +29,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.springframework.core.ParameterizedTypeReference; +import org.springframework.core.SpringProperties; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -82,6 +83,7 @@ import org.springframework.web.util.UriTemplateHandler; * @author Roy Clarkson * @author Juergen Hoeller * @author Sam Brannen + * @author Sebastien Deleuze * @since 3.0 * @see HttpMessageConverter * @see RequestCallback @@ -90,6 +92,13 @@ import org.springframework.web.util.UriTemplateHandler; */ public class RestTemplate extends InterceptingHttpAccessor implements RestOperations { + /** + * Boolean flag controlled by a {@code spring.xml.ignore} system property that instructs Spring to + * ignore XML, i.e. to not initialize the XML-related infrastructure. + *

The default is "false". + */ + private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore"); + private static final boolean romePresent; private static final boolean jaxb2Present; @@ -138,11 +147,13 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat this.messageConverters.add(new ByteArrayHttpMessageConverter()); this.messageConverters.add(new StringHttpMessageConverter()); this.messageConverters.add(new ResourceHttpMessageConverter(false)); - try { - this.messageConverters.add(new SourceHttpMessageConverter<>()); - } - catch (Error err) { - // Ignore when no TransformerFactory implementation is available + if (!shouldIgnoreXml) { + try { + this.messageConverters.add(new SourceHttpMessageConverter<>()); + } + catch (Error err) { + // Ignore when no TransformerFactory implementation is available + } } this.messageConverters.add(new AllEncompassingFormHttpMessageConverter()); @@ -151,11 +162,13 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat this.messageConverters.add(new RssChannelHttpMessageConverter()); } - if (jackson2XmlPresent) { - this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter()); - } - else if (jaxb2Present) { - this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter()); + if (!shouldIgnoreXml) { + if (jackson2XmlPresent) { + this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter()); + } + else if (jaxb2Present) { + this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter()); + } } if (jackson2Present) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java index c64fcc7ed8..b85cd5cdb3 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java @@ -34,6 +34,7 @@ import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; +import org.springframework.core.SpringProperties; import org.springframework.core.convert.converter.Converter; import org.springframework.format.Formatter; import org.springframework.format.FormatterRegistry; @@ -183,6 +184,13 @@ import org.springframework.web.util.UrlPathHelper; */ public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware { + /** + * Boolean flag controlled by a {@code spring.xml.ignore} system property that instructs Spring to + * ignore XML, i.e. to not initialize the XML-related infrastructure. + *

The default is "false". + */ + private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore"); + private static final boolean romePresent; private static final boolean jaxb2Present; @@ -427,7 +435,7 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv map.put("atom", MediaType.APPLICATION_ATOM_XML); map.put("rss", MediaType.APPLICATION_RSS_XML); } - if (jaxb2Present || jackson2XmlPresent) { + if (!shouldIgnoreXml && (jaxb2Present || jackson2XmlPresent)) { map.put("xml", MediaType.APPLICATION_XML); } if (jackson2Present || gsonPresent || jsonbPresent) { @@ -857,11 +865,13 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv messageConverters.add(new StringHttpMessageConverter()); messageConverters.add(new ResourceHttpMessageConverter()); messageConverters.add(new ResourceRegionHttpMessageConverter()); - try { - messageConverters.add(new SourceHttpMessageConverter<>()); - } - catch (Throwable ex) { - // Ignore when no TransformerFactory implementation is available... + if (!shouldIgnoreXml) { + try { + messageConverters.add(new SourceHttpMessageConverter<>()); + } + catch (Throwable ex) { + // Ignore when no TransformerFactory implementation is available... + } } messageConverters.add(new AllEncompassingFormHttpMessageConverter()); @@ -870,15 +880,17 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv messageConverters.add(new RssChannelHttpMessageConverter()); } - if (jackson2XmlPresent) { - Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.xml(); - if (this.applicationContext != null) { - builder.applicationContext(this.applicationContext); + if (!shouldIgnoreXml) { + if (jackson2XmlPresent) { + Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.xml(); + if (this.applicationContext != null) { + builder.applicationContext(this.applicationContext); + } + messageConverters.add(new MappingJackson2XmlHttpMessageConverter(builder.build())); + } + else if (jaxb2Present) { + messageConverters.add(new Jaxb2RootElementHttpMessageConverter()); } - messageConverters.add(new MappingJackson2XmlHttpMessageConverter(builder.build())); - } - else if (jaxb2Present) { - messageConverters.add(new Jaxb2RootElementHttpMessageConverter()); } if (jackson2Present) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/support/RouterFunctionMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/support/RouterFunctionMapping.java index ca4a1a91b8..ba5c38715e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/support/RouterFunctionMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/support/RouterFunctionMapping.java @@ -26,6 +26,7 @@ import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; +import org.springframework.core.SpringProperties; import org.springframework.http.converter.ByteArrayHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.StringHttpMessageConverter; @@ -47,10 +48,19 @@ import org.springframework.web.servlet.handler.AbstractHandlerMapping; * {@linkplain org.springframework.core.annotation.Order order}. * * @author Arjen Poutsma + * @author Sebastien Deleuze * @since 5.2 */ public class RouterFunctionMapping extends AbstractHandlerMapping implements InitializingBean { + /** + * Boolean flag controlled by a {@code spring.xml.ignore} system property that instructs Spring to + * ignore XML, i.e. to not initialize the XML-related infrastructure. + *

The default is "false". + */ + private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore"); + + @Nullable private RouterFunction routerFunction; @@ -152,11 +162,13 @@ public class RouterFunctionMapping extends AbstractHandlerMapping implements Ini messageConverters.add(new ByteArrayHttpMessageConverter()); messageConverters.add(new StringHttpMessageConverter()); - try { - messageConverters.add(new SourceHttpMessageConverter<>()); - } - catch (Error err) { - // Ignore when no TransformerFactory implementation is available + if (!shouldIgnoreXml) { + try { + messageConverters.add(new SourceHttpMessageConverter<>()); + } + catch (Error err) { + // Ignore when no TransformerFactory implementation is available + } } messageConverters.add(new AllEncompassingFormHttpMessageConverter()); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java index 1e7751827d..cf04903006 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java @@ -32,6 +32,7 @@ import org.springframework.aop.support.AopUtils; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; +import org.springframework.core.SpringProperties; import org.springframework.http.HttpStatus; import org.springframework.http.converter.ByteArrayHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; @@ -71,11 +72,20 @@ import org.springframework.web.servlet.support.RequestContextUtils; * * @author Rossen Stoyanchev * @author Juergen Hoeller + * @author Sebastien Deleuze * @since 3.1 */ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExceptionResolver implements ApplicationContextAware, InitializingBean { + /** + * Boolean flag controlled by a {@code spring.xml.ignore} system property that instructs Spring to + * ignore XML, i.e. to not initialize the XML-related infrastructure. + *

The default is "false". + */ + private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore"); + + @Nullable private List customArgumentResolvers; @@ -108,11 +118,13 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce this.messageConverters = new ArrayList<>(); this.messageConverters.add(new ByteArrayHttpMessageConverter()); this.messageConverters.add(new StringHttpMessageConverter()); - try { - this.messageConverters.add(new SourceHttpMessageConverter<>()); - } - catch (Error err) { - // Ignore when no TransformerFactory implementation is available + if(!shouldIgnoreXml) { + try { + this.messageConverters.add(new SourceHttpMessageConverter<>()); + } + catch (Error err) { + // Ignore when no TransformerFactory implementation is available + } } this.messageConverters.add(new AllEncompassingFormHttpMessageConverter()); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java index 66049d310e..43fd25fa22 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java @@ -37,6 +37,7 @@ import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.MethodIntrospector; import org.springframework.core.ParameterNameDiscoverer; import org.springframework.core.ReactiveAdapterRegistry; +import org.springframework.core.SpringProperties; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.core.log.LogFormatUtils; import org.springframework.core.task.AsyncTaskExecutor; @@ -108,6 +109,7 @@ import org.springframework.web.util.WebUtils; * * @author Rossen Stoyanchev * @author Juergen Hoeller + * @author Sebastien Deleuze * @since 3.1 * @see HandlerMethodArgumentResolver * @see HandlerMethodReturnValueHandler @@ -115,6 +117,13 @@ import org.springframework.web.util.WebUtils; public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter implements BeanFactoryAware, InitializingBean { + /** + * Boolean flag controlled by a {@code spring.xml.ignore} system property that instructs Spring to + * ignore XML, i.e. to not initialize the XML-related infrastructure. + *

The default is "false". + */ + private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore"); + /** * MethodFilter that matches {@link InitBinder @InitBinder} methods. */ @@ -196,11 +205,13 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter this.messageConverters = new ArrayList<>(4); this.messageConverters.add(new ByteArrayHttpMessageConverter()); this.messageConverters.add(new StringHttpMessageConverter()); - try { - this.messageConverters.add(new SourceHttpMessageConverter<>()); - } - catch (Error err) { - // Ignore when no TransformerFactory implementation is available + if (!shouldIgnoreXml) { + try { + this.messageConverters.add(new SourceHttpMessageConverter<>()); + } + catch (Error err) { + // Ignore when no TransformerFactory implementation is available + } } this.messageConverters.add(new AllEncompassingFormHttpMessageConverter()); }