Skip to content

Commit

Permalink
Provide a flag to disable XML support
Browse files Browse the repository at this point in the history
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 spring-projectsgh-25151
  • Loading branch information
sdeleuze authored and kenny5he committed Jun 21, 2020
1 parent a1db26b commit e44828e
Show file tree
Hide file tree
Showing 10 changed files with 185 additions and 56 deletions.
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -71,6 +71,7 @@
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;
Expand All @@ -84,13 +85,22 @@
*
* @author Juergen Hoeller
* @author Rob Harrop
* @author Sebastien Deleuze
* @since 1.2.6
* @see java.beans.PropertyEditorManager
* @see java.beans.PropertyEditorSupport#setAsText
* @see java.beans.PropertyEditorSupport#setValue
*/
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.
* <p>The default is "false".
*/
private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore");


@Nullable
private ConversionService conversionService;

Expand Down Expand Up @@ -208,7 +218,9 @@ private void createDefaultEditors() {
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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
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;
Expand All @@ -41,13 +42,21 @@
*
* @author Juergen Hoeller
* @author Rob Harrop
* @author Sebastien Deleuze
* @since 2.0
* @see PropertiesLoaderSupport
*/
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.
* <p>The default is "false".
*/
private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore");


/**
* Load properties from the given EncodedResource,
Expand Down Expand Up @@ -88,6 +97,9 @@ static void fillProperties(Properties props, EncodedResource resource, Propertie
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);
}
Expand Down Expand Up @@ -133,6 +145,9 @@ public static void fillProperties(Properties props, Resource resource) throws IO
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 {
Expand Down Expand Up @@ -180,6 +195,9 @@ public static Properties loadAllProperties(String resourceName, @Nullable ClassL
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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -23,6 +23,8 @@
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}.
Expand All @@ -46,13 +48,22 @@
* "defaultEncoding" and "fileEncodings" properties).
*
* @author Juergen Hoeller
* @author Sebastien Deleuze
* @since 10.03.2004
* @see java.util.Properties
* @see java.util.Properties#load
* @see java.util.Properties#store
*/
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.
* <p>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);
Expand All @@ -75,16 +86,25 @@ public void store(Properties props, Writer writer, String header) throws IOExcep

@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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
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;
Expand Down Expand Up @@ -70,6 +71,13 @@
*/
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.
* <p>The default is "false".
*/
private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore");

static final boolean jackson2Present;

private static final boolean jackson2SmilePresent;
Expand Down Expand Up @@ -284,7 +292,7 @@ private void initCodec(@Nullable Object codec) {
((AbstractJackson2Decoder) codec).setMaxInMemorySize(size);
}
}
if (jaxb2Present) {
if (jaxb2Present && !shouldIgnoreXml) {
if (codec instanceof Jaxb2XmlDecoder) {
((Jaxb2XmlDecoder) codec).setMaxInMemorySize(size);
}
Expand Down Expand Up @@ -353,7 +361,7 @@ final List<HttpMessageReader<?>> getObjectReaders() {
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()));
}
Expand Down Expand Up @@ -449,7 +457,7 @@ final List<HttpMessageWriter<?>> getBaseObjectWriters() {
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()));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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;
Expand All @@ -32,10 +33,18 @@
*
* @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.
* <p>The default is "false".
*/
private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore");

private static final boolean jaxb2Present;

private static final boolean jackson2Present;
Expand All @@ -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 (jaxb2Present && !jackson2XmlPresent) {
addPartConverter(new Jaxb2RootElementHttpMessageConverter());
if (!shouldIgnoreXml) {
try {
addPartConverter(new SourceHttpMessageConverter<>());
}
catch (Error err) {
// Ignore when no TransformerFactory implementation is available
}

if (jaxb2Present) {
addPartConverter(new Jaxb2RootElementHttpMessageConverter());
}
}

if (jackson2Present) {
Expand All @@ -82,7 +93,7 @@ else if (jsonbPresent) {
addPartConverter(new JsonbHttpMessageConverter());
}

if (jackson2XmlPresent) {
if (jackson2XmlPresent && !shouldIgnoreXml) {
addPartConverter(new MappingJackson2XmlHttpMessageConverter());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
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;
Expand Down Expand Up @@ -82,6 +83,7 @@
* @author Roy Clarkson
* @author Juergen Hoeller
* @author Sam Brannen
* @author Sebastien Deleuze
* @since 3.0
* @see HttpMessageConverter
* @see RequestCallback
Expand All @@ -90,6 +92,13 @@
*/
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.
* <p>The default is "false".
*/
private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore");

private static final boolean romePresent;

private static final boolean jaxb2Present;
Expand Down Expand Up @@ -138,11 +147,13 @@ public RestTemplate() {
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());

Expand All @@ -151,11 +162,13 @@ public RestTemplate() {
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) {
Expand Down
Loading

0 comments on commit e44828e

Please sign in to comment.