Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

November Discount Launch 2022 – Top
We’re finally running a Black Friday launch. All Courses are 30% off until end-of-day today:

>> GET ACCESS NOW

NPI – Lightrun – Spring (partner)

We rely on other people’s code in our own work. Every day. It might be the language you’re writing in, the framework you’re building on, or some esoteric piece of software that does one thing so well you never found the need to implement it yourself.

The problem is, of course, when things fall apart in production - debugging the implementation of a 3rd party library you have no intimate knowledge of is, to say the least, tricky. It’s difficult to understand what talks to what and, specifically, which part of the underlying library is at fault.

Lightrun is a new kind of debugger.

It's one geared specifically towards real-life production environments. Using Lightrun, you can drill down into running applications, including 3rd party dependencies, with real-time logs, snapshots, and metrics. No hotfixes, redeployments, or restarts required.

Learn more in this quick, 5-minute Lightrun tutorial:

>> The Essential List of Spring Boot Annotations and Their Use Cases

1. Overview

When we're injecting runtime properties into our Spring applications, we may define bean classes for groups of custom properties.

IntelliJ provides help and auto-complete for the built-in properties beans. However, it needs a little help to provide these for custom properties.

In this short tutorial, we'll look at how to expose these properties to IntelliJ to make the development process easier.

2. Custom Properties

Let's have a look at the on-screen help IntelliJ can provide us regarding our application's properties:

IntelliJCannotResolveCustomPropertyAutoCompletion

Here, the properties url and timeout-in-milliseconds are custom properties. We can see a description, type, and an optional default value.

But, if a property is unknown, IntelliJ will show us a warning:

IntelliJCannotResolveCustomProperty-2

This is because, without metadata, IntelliJ cannot help us.

Now let's take a look at what we have to do to fix this.

3. Dependencies

First, we need to add the spring-boot-configuration-processor dependency to our pom.xml:

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

The spring-boot-configuration-processor is invoked each time we build our project. It will create the metadata files in target/classes/META-INF/. 

The dependency is marked as optional, which means that it is not inherited when somebody uses our project as a dependency.

Next, we'll see where the spring-boot-configuration-processor gets the information used to create the metadata.

4. Configuration Metadata with @ConfigurationProperties

We define our properties in a class annotated with @ConfigurationProperties:

@Configuration
@ConfigurationProperties(prefix = "com.baeldung")
public class CustomProperties {

    /**
     * The url to connect to.
     */
    String url;

    /**
     * The time to wait for the connection.
     */
    private int timeoutInMilliSeconds = 1000;

    // Getters and Setters

}

Here, the class contains the property names, their types, and any defaults provided in the initializer list. Also, the Javadoc provides descriptions of each property.

During a build, the annotation processor searches for all classes that are annotated with @ConfigurationProperties. It generates custom property metadata for each instance variable of the class.

5. Configuration Metadata File

5.1. Format of the Metadata File

The metadata file that describes the custom properties drives the contextual help in IntelliJ, for example:

{
  "groups": [
    {
      "name": "com.baeldung",
      "type": "com.baeldung.configuration.processor.CustomProperties",
      "sourceType": "com.baeldung.configuration.processor.CustomProperties"
    }
  ],
  "properties": [
    {
      "name": "com.baeldung.url",
      "type": "java.lang.String",
      "description": "The url to connect to.",
      "sourceType": "com.baeldung.configuration.processor.CustomProperties"
    },
    {
      "name": "com.baeldung.timeout-in-milli-seconds",
      "type": "java.lang.Integer",
      "description": "The time to wait for the connection.",
      "sourceType": "com.baeldung.configuration.processor.CustomProperties",
      "defaultValue": 1000
    }
  ],
  "hints": []
}

As the annotation processor generates this file for us from our code, there's no need to look at or edit this file directly.

5.2. Metadata Without a ConfigurationProperties Bean

If we have existing properties that are not introduced by a @ConfigurationProperties, but still want their metadata file, then IntelliJ can help.

Let's take a closer look at the warning message from before:

IntelliJCannotResolveCustomProperty-2-1

Here we see a Define configuration key option, which we can use to create an additional-spring-configuration-metadata.json file. The created file will look like:

{
  "properties": [
    {
      "name": "com.baeldung.timeoutInMilliSeconds",
      "type": "java.lang.String",
      "description": "Description for com.baeldung.timeoutInMilliSeconds."
    }
  ]
}

As there's no information about the property from anywhere else, we'll have to manually edit the metadata inside it. The default type is always String.

Let's put some extra information into the file:

{
  "properties": [
    {
      "name": "com.baeldung.timeout-in-milli-seconds",
      "type": "java.lang.Integer",
      "description": "The time to wait for the connection.",
      "sourceType": "com.baeldung.configuration.processor.CustomProperties",
      "defaultValue": 1000
    }
  ]
}

Note that we'll need to rebuild the project to see the new property come up in auto-complete.

Also, we should note that the option to generate this metadata file is also available via IntelliJ's Alt+ENTER shortcut over an unknown property.

6. Conclusion

In this article, we looked at how IntelliJ uses the configuration property metadata to provide help with our properties files.

We saw how to use Spring's annotation processor to generate the metadata from custom classes. Then, we saw how to use a shortcut in IntelliJ to create a metadata file to edit manually.

As always, the code from the examples in this article can be found over on GitHub.

November Discount Launch 2022 – Bottom
We’re finally running a Black Friday launch. All Courses are 30% off until end-of-day today:

>> GET ACCESS NOW

Generic footer banner
2 Comments
Oldest
Newest
Inline Feedbacks
View all comments
Comments are closed on this article!