Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

spring-boot-configuration-processor is not working on maven submodule project

I have a maven multi module project with one parent and three child modules. The application uses spring boot. In one of the child modules, I have the SpringBootApplication:

@SpringBootApplication
@EnableConfigurationProperties({AppProperties.class})
public class MainSpringBootApplication {
    public static void main(String[] args) {
        SpringApplication.run(MainSpringBootApplication.class, args);
    }
}

The App Properties are in the same module:

@Data
@ConfigurationProperties(prefix = "asdf")
public class AppProperties {
...
}

In the pom.xml of that module there is a dependency for the spring-boot-configuration-processor:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-configuration-processor</artifactId>
  <optional>true</optional>
</dependency>

Now the problem is, when I run mvn install on the parent project, the target/classes/META-INF/spring-configuration-metadata.json file within this child module is not created. When I modify the pom of that child module to directly inherit from:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.3.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

and do mvn install directly on the child module, the target/classes/META-INF/spring-configuration-metadata.json file is generated.

Do you have any hints?

like image 575
Ralf Avatar asked May 21 '19 08:05

Ralf


People also ask

What is spring-boot configuration processor dependency?

spring-boot-configuration-processor is an annotation processor that generates metadata about classes in your application that are annotated with @ConfigurationProperties .

What are the ways in which spring-boot can read configurations?

Spring Boot lets you externalize your configuration so that you can work with the same application code in different environments. You can use properties files, YAML files, environment variables, and command-line arguments to externalize configuration.

Why do we need spring-boot Maven plugin?

The Spring Boot Maven Plugin provides Spring Boot support in Apache Maven. It allows you to package executable jar or war archives, run Spring Boot applications, generate build information and start your Spring Boot application prior to running integration tests.


2 Answers

I explicitly added:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.0</version>
    <configuration>
      <annotationProcessorPaths>
        <annotationProcessorPath>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-configuration-processor</artifactId>
          <version>2.1.5.RELEASE</version>
        </annotationProcessorPath>
      </annotationProcessorPaths>
    </configuration>
  </plugin>

to the plugins section of the pom of the child module containing the @ConfigurationProperties annotated class. Now target/classes/META-INF/spring-configuration-metadata.json is generated.

like image 158
Ralf Avatar answered Nov 15 '22 04:11

Ralf


There are two options I am aware of. First one is my favourite (especially because it configures the order of APT libraries - the order of code generation). But based, say, on the IDE auto-discovery mechanism, the 2nd one is also a good bet.

Both ones are primarily targeting the minimum size of the final artefact (dependencies' scope), which, for me is very important. Not to increase the deliverable/archetype size with useless dependencies (apt libraries are needed only at compile time) is very important in the era of k8s/docker/cloud (resource efficiency).

So, without further ado, the options:

  1. Use APT libraries only in maven compiler plugin configuration (nothing in dependencies).
           <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-compiler-plugin</artifactId>
               <version>${maven-compiler-plugin.version}</version>
               <configuration>
                   <annotationProcessorPaths>
                       <path>
                           <groupId>org.projectlombok</groupId>
                           <artifactId>lombok</artifactId>
                           <version>${lombok.version}</version>
                       </path>
                       <path>
                           <groupId>org.springframework.boot</groupId>
                           <artifactId>spring-boot-configuration-processor</artifactId>
                           <version>${spring-boot.version}</version>
                       </path>
                   </annotationProcessorPaths>
               </configuration>
           </plugin>
  1. This option is useful for the case the maven-compiler-plugin is not configured in plugins/pluginsManagement (but probably by means of its properties).

       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-configuration-processor</artifactId>
           <scope>provided</scope>
       </dependency>

       <dependency>
           <groupId>org.projectlombok</groupId>
           <artifactId>lombok</artifactId>
           <scope>provided</scope>
       </dependency>

Notes:

  • For option 2, scope provided is important, because it will allow to use the APT during the compilation but won't be included in the final artefact).
  • On the other hand (back to your question), in order to generate documentation in target/classes/META-INF/spring-configuration-metadata.json from the java doc, for lombok based java classes, you need these as well (@Getter and @Setter - are both needed).
@Setter
@Getter
@ConfigurationProperties(prefix = "asdf")
public class AppProperties {

   /**
    * foo - Should not be null or empty.
    */
   private Map<String, String> foo;

and the following maven compiler plugin configuration as property (or in the plugin configuration).

   <maven.compiler.parameters>true</maven.compiler.parameters>
  • After the compilation the IDE will parse the spring-configuration-metadata.json file and offer suggestion/quick doc/autocomplete in application.properties/application.yml.

Kr

like image 22
jtonic Avatar answered Nov 15 '22 05:11

jtonic