7

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?

Ralf
  • 453
  • 1
  • 4
  • 15

3 Answers3

6

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

jtonic
  • 609
  • 1
  • 7
  • 10
5

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.

Ralf
  • 453
  • 1
  • 4
  • 15
0

Instead of using this lib "import org.springframework.boot.configurationprocessor.json.JSONObject;", I changed to use "import org.json.JSONObject;".

I don't know exact reason but i tried and run well. You can try this solution.

  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community May 13 '23 at 04:49