7

Source code that reproduces the problem: link.

Suppose I have this kind of structure of configuration properties:

    @Data
    @ConfigurationProperties(prefix = "props")
    public class ConfigProperties {
    
        private String testString;
        private Map<String, InnerConfigProperties> testMap;
    }
    @Data
    public class InnerConfigProperties {
    
        private String innerString;
        private Integer innerInt;
    }

In application.yml I set them in this way:

props:
  testString: asdadasd
  somWrongProperty: asdasd
  testMap:
    key1:
      innerString: value1
      innerInt: 1
      someInnerWrongProperty: wrongvalue
    key2:
      innerString: value2
      innerInt: 2

After launching annotation processing only the simple properties work correctly (you can navigate to their declaration by clicking with ctrl, also autocomplete for them works). Also, IDEA detects if the property is incorrect and highlights it.

For nested structures (which are map values) both of these features don't seem to work properly. You still can click on them but IDEA will navigate to the map declaration. Also, code completion for map values and highlighting of the wrong fields don't work.

Screenshot from IDEA:

enter image description here

Does anybody know how to make it work correctly? Feel free to use the attached example code.

Thanks in advance.

UPDATE

Seems to be fixed in Intellij IDEA 2022.1. Related issues: IDEA-151708 and IDEA-159276.

Nice bugfix productivity though.

amseager
  • 5,795
  • 4
  • 24
  • 47
  • your code perfectly works for me, can you show expected and actual output ? – Ryuzaki L Dec 20 '19 at 17:31
  • It works, yes, and properties are set correctly. But I was talking about code completion and highlighting wrong properties in `application.yml` as shown on the screenshot. For example, you cannot create a new `String` key ("key3" or smth) and then use `ctrl+space` in order to get possible values (`innerString` and `innerInt`). Also, `someInnerWrongProperty` is not defined inside `InnerConfigProperties` class, but it's not highlighted as the wrong value (like `someWrongProperty` for class `ConfigProperties`) – amseager Dec 20 '19 at 18:23
  • They will be ignored @amseager – Ryuzaki L Dec 20 '19 at 18:24
  • Once again: I agree that the code works well. But I'm asking about the usability in IDEA. I want to type props: -> testMap -> key , then press "ctrl-space" and see the possible values, in this case - only "innerString" and "innerInt". If I type something else, it should be highlighted as the wrong property. – amseager Jan 16 '20 at 11:28
  • It's not a spring boot issue but an IntelliJ issue, please change question tags. – akuma8 Jan 17 '20 at 15:53
  • 2
    @akuma8 I added intellij-idea tag (it was there initially but then removed by someone else) – amseager Jan 17 '20 at 15:56
  • Does this answer your question? [Spring configuration properties metadata json for nested list of Objects](https://stackoverflow.com/questions/41417933/spring-configuration-properties-metadata-json-for-nested-list-of-objects) – Amit Goldstein Jan 25 '21 at 14:56

2 Answers2

3

I believe you're asking about the added

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

This is basically an annotation processor - a special hook into compilation process that can detect classes annotated with some annotation during compile time and generate some resources based on that definition. Some annotation processor generate other source files, this one however introspects the classes annotated with @ConfigurationProperties by reflection and based on the field names and types found in this classes it generates a special json file (META-INF/spring-configuration-metadata.json in the target build directory).

You can open it up and see how does it look like.

Now a couple of notes on this process:

  1. Since it happens during the compilation - it doesn't look at application.yaml
  2. The generated JSON in general is not used by spring boot itself during the runtime but intended for IDEs so that they could build some nifty integrations. That's what IntelliJ basically does.

Now, IntelliJ (Only Ultimate Edition, since community edition doesn't include any integration with spring) can indeed read this file, and provide some autocompletion features.

But Based on the information provided in the configuration properties that include Maps an annotation processor (that again runs during the compilation and has an access to the class only) merely cannot generate correct values of keys for example. So IntelliJ won't offer you to chose from key1, key2, since they do not exist in the configuration properties java files. That's why it doesn't work. Bottom Line, IntelliJ is not guilty, it does the best it can :)

In terms of resolution:

There are two paths you can try:

  1. Instead of using Strings as keys, use an enum. Since it will have a finite and well defined set of values, probably the annotation processor will generate a better json (if it doesn't - its a bug or, rather a request for enhancement, in the annotation processor)

  2. Assuming, that the annotation processor does its best job, but not always succeeds, you can define the json manually as described in Spring Boot Documentation

Mark Bramnik
  • 39,963
  • 4
  • 57
  • 97
  • Yes, that makes sense. I'll try to play with `additional-spring-configuration-metadata.json` then. Thank you! – amseager Jan 24 '20 at 09:44
1

According to current documentation for auto-completing-code, there is no such way that IntelliJ IDEA will suggest you the next possible key and will notify you for incorrect value such as somWrongProperty or someInnerWrongProperty

What I found somewhat related and useful for the above use-case is Expand a string at caret to an existing word

  • Press Alt+/ or choose Code | Completion | Cyclic Expand Word to search for matching words before the caret.

  • Press Shift+Alt+/ or choose Code | Completion | Cyclic Expand Word (Backward) to search for matching words after the caret and in other open files.

enter image description here


Code Style. YAML We can customize the code style for YAML as following but however there is no option for auto-complete and error for above use-case

File | Settings | Editor | Code Style | YAML for Windows and Linux
IntelliJ IDEA | Preferences | Editor | Code Style | YAML for macOS Ctrl+Alt+S


Plugins

Further, I have gone through the plugins to achieve the use-case and there are some useful plugins that convert properties to yaml but nothing related to use-case. You might need to wait or create similar kinds of the plugin. You might find this helpful

enter image description here

Romil Patel
  • 12,879
  • 7
  • 47
  • 76
  • "there is no such way that IntelliJ IDEA will suggest you the next possible key and will notify you for incorrect value such as somWrongProperty or someInnerWrongProperty" - but on my screenshot you can see "somWrongProperty" highlighted. Do you have community or ultimate IDEA ? – amseager Jan 18 '20 at 21:44
  • Community. Are you using ultimate? From *If I type something else, it should be highlighted as wrong property* I understood that you are trying to achieve wrong property indication. If it already suggests the wrong property in ultimate version then What you are trying to achieve, can you please share the details – Romil Patel Jan 19 '20 at 05:40
  • It seems to work only for simple properties but not for structures like `Map` (in that case IDEA's autocompletion doesn't work for InnerComplexStructure's fields, also wrong fields of it are not highlighted). You can check it on trial or EAP version of IDEA ultimate. – amseager Jan 19 '20 at 18:57