11

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?

zeodtr
  • 10,645
  • 14
  • 43
  • 60
  • 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 https://github.com/spring-projects/spring-boot/issues/121 . – M. Deinum Nov 19 '13 at 10:46
  • Thank you @M.Deinum, but it does not work. I updated my question with my new code. – zeodtr Nov 19 '13 at 12:20
  • Also thank you @M.Deinum to mention the Spring Boot issue. – zeodtr Nov 19 '13 at 12:22
  • `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 Nov 19 '13 at 15:42
  • @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 (http://stackoverflow.com/questions/20064241/how-to-service-external-static-html-files-in-spring-boot-embedded-tomcat), which you already read. – zeodtr Nov 20 '13 at 00:37

2 Answers2

8

The most correct answer to the original question 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 list of properties in the user guide that is accurate for nearly everything supported by Spring Boot itself (but not other libraries that build on top of it). The definitive list comes from searching the source code for @ConfigurationProperties and @Value annotations. There is also some general advice in the howto docs.

Dave Syer
  • 56,583
  • 10
  • 155
  • 143
  • Thanks you so much, This is what I really want to know. – Whiteship Dec 18 '13 at 03:02
  • The link to `application.yml` is not valid now. – TheKojuEffect May 03 '14 at 02:09
  • It moved to the main user guide: http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#common-application-properties – Dave Syer May 03 '14 at 06:58
  • Dave, is there a way to get a list of all resolved properties without instantiating the entire SpringApplication instance? That is, at some point before the application fully starts up and the object graph created, the full set of all resolved properties must be known. Can you get that at runtime? I'd like a list of properties to examine. – ae6rt Aug 09 '14 at 01:50
  • It think it depends what you really want. Do you need to run the app, or are you running it anway – Dave Syer Aug 10 '14 at 03:07
  • I don't need to run the app. In fact it would be way more interesting if I did not have to. – ae6rt Aug 11 '14 at 18:10
  • With the current code (1.1.5) I believe starting the app is the best way to get full insight out of the box. You could look at the work Stephane started: https://github.com/snicoll/spring-boot/tree/gh-1001 (for https://github.com/spring-projects/spring-boot/issues/1001) if you want something that works out of band. – Dave Syer Aug 12 '14 at 00:36
  • Dave - will be great if you can point to the source where we can look to see the supported props. I think this will be more explorative and dev style. I did find this myself in the past but lost track of how i did this. What i mean is - is there a jar we can look at and see the props available to the application.. some thing like just as an example auto-configure jar etc... plz reply.. this info will be super useful for devs.\ – samshers Aug 05 '22 at 04:36
  • The properties supported by spring boot itself are in the docs: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#appendix.application-properties – Dave Syer Sep 15 '22 at 10:45
0

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!

Paolo Biavati
  • 609
  • 10
  • 19