9
votes

Spring Boot document says that we can set properties in application.properties file.
But I cannot find a document that lists available properties that can be set.
Where can I find such a document?

For example, I want to set documentRoot for embedded servlet.
I found that the setDocumentRoot() method is implemented in AbstractEmbeddedServletContainerFactory.java.
But I don't know when or where to call the method, or the name of property that can be set in application.properties.
I think it should be easy, since Spring Boot's very purpose is to ease the configuration.

Thanks in advance.

UPDATE:

As M. Deinum sugggested, I added 'server.document-root: someDirectoryName' to the application.properties, but following error occured.

Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'document-root' of bean class [org.springframework.boot.context.embedded.properties.ServerProperties]: Bean property 'document-root' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
    at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1057)
    at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:915)
    at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:82)
    at org.springframework.validation.DataBinder.applyPropertyValues(DataBinder.java:730)
    at org.springframework.validation.DataBinder.doBind(DataBinder.java:626)
    at org.springframework.boot.bind.RelaxedDataBinder.doBind(RelaxedDataBinder.java:78)
    at org.springframework.validation.DataBinder.bind(DataBinder.java:611)
    at org.springframework.boot.bind.PropertiesConfigurationFactory.doBindPropertiesToTarget(PropertiesConfigurationFactory.java:232)
    at org.springframework.boot.bind.PropertiesConfigurationFactory.bindPropertiesToTarget(PropertiesConfigurationFactory.java:204)
    at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessAfterInitialization(ConfigurationPropertiesBindingPostProcessor.java:312)
    ... 31 more

I think it is because of the way org.springframework.boot.context.embedded.properties.ServerProperties implemented. (See https://github.com/spring-projects/spring-boot/blob/97cb7f096798ecd016de71f892fa55585d45f5eb/spring-boot/src/main/java/org/springframework/boot/context/embedded/properties/ServerProperties.java)

It declares '@ConfigurationProperties(name = "server", ignoreUnknownFields = false)'. So, it manages the application properties that starts with 'server', and disallowes unknown property name.
And it does not support documentRoot getter/setter.

BTW, ServerProperties class is made to a Bean by org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration (See https://github.com/spring-projects/spring-boot/blob/97cb7f096798ecd016de71f892fa55585d45f5eb/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerPropertiesAutoConfiguration.java) so that it can participate in the configuration process.

So, I tried to implement ServerProperties-like one and ServerPropertiesAutoConfiguration-like one myself.
The code is as follows:

package com.sample.server;

import java.io.File;

import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SampleConfiguration
{
    @Bean
    public SampleServerProperties sampleServerProperties()
    {
        return new SampleServerProperties();
    }

    @ConfigurationProperties(name = "sample.server")
    public static class SampleServerProperties
        implements EmbeddedServletContainerCustomizer 
    {
        private String documentRoot;
        public String getDocumentRoot()
        {
            return documentRoot;
        }
        public void setDocumentRoot(String documentRoot)
        {
            System.out.println("############## setDocumentRoot");
            this.documentRoot = documentRoot;
        }

        @Override
        public void customize(ConfigurableEmbeddedServletContainerFactory factory)
        {
            if (getDocumentRoot() != null)
            {
                factory.setDocumentRoot(new File(getDocumentRoot()));
            }
        }
    }
}

And added following line to application.properties.

sample.server.documentRoot: someDirectoryName

...And it works!

"############## setDocumentRoot" is printed to the console, and the document root is actually set.

So, I'm happy now, but is this the right way to do it?

3
use server.document-root as the name of a the property. Basically take the name of the property and add a - gives you the name of the property. So basically server.context-path sets the base URL for your application. Also see github.com/spring-projects/spring-boot/issues/121 . - M. Deinum
Thank you @M.Deinum, but it does not work. I updated my question with my new code. - zeodtr
Also thank you @M.Deinum to mention the Spring Boot issue. - zeodtr
ServerProperties (and all beans marked @ConfigurationProperties) bind to external properties, as you have discovered. They also bind in a "relaxed" way (so hyphens and underscores are accepted in place of camelCase). But ServerProperties does not have a documentRoot (hence the error message). What were you trying to achieve with that exactly? - Dave Syer
@DaveSyer Thank you for the information. I want to be able to change the document root to wherever I want to, regardless of the classpath and current directory, by specifying the direcotry in application.properties. See my another question (stackoverflow.com/questions/20064241/…), which you already read. - zeodtr

3 Answers

7
votes

The most correct answer to the original question at the moment is that there is not (and technically cannot be) an exhaustive list in a single location. We can and will document as much of it as we can (when time permits - contributions gratefully accepted). There is a manually curated list of properties with a non-exhaustive and possibly inaccurate list in he user guide. The definitive list comes from searching the source code for @ConfigurationProperties and @Value annotations, as well as the occasional use of RelaxedEnvironment (c.f. here). There is also some general advice in the howto docs.

0
votes

Your question is very appropriate. I found an alternative simpler solution, when I was looking for ajp configuration (http://www.appsdev.is.ed.ac.uk/blog/?p=525) :

set in application.properties:

tomcat.server.document-root=/your/document/root/

in your application class:

1) put the property using @Value annotiation

@Value("${tomcat.server.document-root}")
String documentRoot;

2) and add the bean

@Bean
public EmbeddedServletContainerFactory servletContainer() {

    TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();

    if (StringUtils.isNotBlank(documentRoot)) {
        tomcat.setDocumentRoot(new File(documentRoot));
    }

    return tomcat;
}

you are done!

0
votes

Here you can find the list of all the properties that can be used in the application.properties file in spring boot.