#ConfigurationProperties Spring Boot Configuration Annotation Processor not found in classpath - spring-boot

I try to make completion for custom properties in Spring Boot.
I tried to create a simple project via IntelliJ IDEA 2016.3:
Created a new Gradle project with Spring Boot Initializer (I haven't checked anything at all).
Created a new class Properties.
When I annotated it with #ConfigurationProperties, the next notification has appeared:
The documentation said that I should add the following to my project:
dependencies {
optional "org.springframework.boot:spring-boot-configuration-processor"
}
compileJava.dependsOn(processResources)
After that, I tried to rebuild the project and enable annotation processors in settings but the notification hasn't gone. Completion doesn't work too (I created a string my).

I had the same problem. I use idea 2017.2 and gradle 4.1,
and some blog said you should add:
dependencies {
optional "org.springframework.boot:spring-boot-configuration-processor"
}
But I changed it to this:
dependencies {
compile "org.springframework.boot:spring-boot-configuration-processor"
}
And the warning is gone.

According to the Spring Boot docs, the correct configuration since Gradle 4.6 is
dependencies {
annotationProcessor group: 'org.springframework.boot', name: 'spring-boot-configuration-processor'
// ...
}
IntelliJ IDEA supports annotationProcessor scope since build 193.3382 (2019.3). Don't forget to enable annotation processing in IntelliJ IDEA settings.

For those who are using maven, Intellij was still not happy with the addition of dependency. Seems like adding annotationProcessorPaths via maven-compiler-plugin finally tamed the beast.
Make sure the version matches your spring dependencies. I suspect it would be already present in your effective POM.
Reason: I was using a custom parent-pom which had a mapstruct annotation processor set in annotationProcessorPaths and that actually triggered IntelliJ to ask for all other annotation processors to be specified manually as well.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>2.0.4.RELEASE</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>

For those using Maven or Gradle, just add the dependency on spring-boot-configuration-processor.
Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
Gradle 4.5 and earlier
dependencies {
compileOnly "org.springframework.boot:spring-boot-configuration-processor"
}
Gradle 4.6 and later
dependencies {
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
}
For more information:
"Generating Your Own Metadata by Using the Annotation Processor"
https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/reference/html/appendix-configuration-metadata.html#configuration-metadata-annotation-processor

It happens to me for two reasons in IDEA:
Double check if your setting is picked (enabled) in IDEA: Preferences->Annotation Processors->Enable annotation processing.
After update your Idea, check your plugins and update them. It happens that plugins become incompatible with your new IDEA version, so just click to update them.

I forgot to add propdeps-plugin. However, I remember that it didn't work for me even with the plugin on 2016.3, So as #CrazyCoder mentioned, try to downgrade Gradle or download the new 2017.1 version (details).
Also you may receive Re-run Spring Boot Configuration Annotation Processor to update generated metadata when you will solve this issue. For this, click Refresh all Gradle projects (in Gradle side menu).

In maven project helps adding dependency spring-boot-configuration-processor and marking main class with #EnableConfigurationProperties(AppProperties.class).
Maybe somebody helps.

In version 2018.3 of IntelliJ, I solved this problem (as per this documentation) in the following way:
With Gradle 4.5 and earlier, the dependency should be declared in the
compileOnly configuration, as shown in the following example:
dependencies {
compileOnly "org.springframework.boot:spring-boot-configuration-processor"
}
With Gradle 4.6 and later, the dependency should be declared in the
annotationProcessor configuration, as shown in the following example:
dependencies {
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
}

For Kotlin projects, the working configuration since Gradle 4.6 is using annotation processor
apply plugin: "kotlin-kapt"
dependencies {
kapt("org.springframework.boot:spring-boot-configuration-processor:$springBootVersion")
compileOnly("org.springframework.boot:spring-boot-configuration-processor:$springBootVersion")
}

You have to mention in the main class the class you want to use #ConfigurationProperties annotation like below.
#EnableConfigurationProperties(AppProperties.class)
The Property Configuration class with #ConfigurationProperties will be like this
import org.springframework.boot.context.properties.ConfigurationProperties;
#ConfigurationProperties(prefix = "app")
public class AppProperties {
String name;
String id;
}
The Main class will be like this
import com.auth2.demo.config.AppProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
#SpringBootApplication
#EnableConfigurationProperties(AppProperties.class)
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}

I had the same problem with IntelliJ version 2018.1.2. I also had to define the actual version of spring-boot-configuration-processor in order to get it worked:
compile('org.springframework.boot:spring-boot-configuration-processor:2.0.1.RELEASE')

following works for me:
buildscript {
repositories {
jcenter()
maven { url 'https://repo.jenkins-ci.org/public/' }
maven { url 'http://repo.spring.io/plugins-release' }
}
dependencies {
classpath "io.spring.gradle:propdeps-plugin:0.0.9.RELEASE"
}
}
...
apply plugin: 'propdeps'
apply plugin: 'propdeps-eclipse'
apply plugin: 'propdeps-idea'
...
dependencyManagement {
imports {
mavenBom 'org.springframework.boot:spring-boot-starter-parent:2.0.0.RELEASE'
}
}
...
dependencies {
compile "org.springframework.boot:spring-boot-starter"
compile "org.springframework.boot:spring-boot-starter-actuator"
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor" // for #ConfigurationProperties, make sure compileJava.dependsOn(processResources)
...
}
compileJava.dependsOn(processResources)

According to the Spring Boot docs, the correct configuration for Gradle 4.5 and earlier is
dependencies {
compileOnly group: 'org.springframework.boot', name: 'spring-boot-configuration-processor'
// ...
}

Spring's website has a tutorial that contains a great explanation how to make it work. Just follow the steps under "Configuration properties" section below.
It has one of the steps which none of other answers mentioned here:
run ./gradlew kaptKotlin manually.
As of Mar 2021, IDEA will still show the warning on top of the Kotlin properties class, but the properties will be recognized and work. You'll be able to navigate from .properties file to the Kotlin properties class, but not the other way around.
https://spring.io/guides/tutorials/spring-boot-kotlin/ scroll down to "Configuration properties" part.
Or the same page on GitHub:
https://github.com/spring-guides/tut-spring-boot-kotlin/blob/master/README.adoc#configuration-properties

Related

Spring Boot Gradle build fails with "Execution failed for task 'bootWarMainClassName'

I have a multi-project gradle build with Spring Boot structured per default gradle conventions.
root
-- common
-- src/main/java
-- bootproject
-- src/main/java
My current project is to (A) upgrade gradle from 5.x to 7.3.x and (B) use embedded tomcat with Spring Boot.
This is a project that has existed for many years and is Spring Boot but has always been deployed traditionally as a WAR file in Tomcat.
I have upgraded gradle to 7.3.3 following the gradle migration guide and have "common" building correctly (java-library). I am now trying to make "bootproject" build correctly again. I have migrated my build.gradle, and compilation happens correctly now but upon executing 'gradlew sub-project:build' I get the error:
Execution failed for task ':tx-main:bootWarMainClassName'.
java.lang.IllegalArgumentException (no error message)
My ROOT build.gradle is simple:
plugins {
id "org.springframework.boot" version "2.6.3"
}
subprojects {
apply plugin: 'java'
group = 'com.blah'
version = '2.1.1'
repositories {
mavenCentral()
}
There is a library sub-project (common) that builds fine.
The Spring Boot subproject build.gradle is:
plugins {
id 'org.springframework.boot'
id 'io.spring.dependency-management'
}
dependencies {
implementation project(path:':common', configuration:'default')
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation ...
}
The main class was originally set up to make the app conventionally deployed (extends SpringBootServletInitializer), but has been replaced with (taken directly from docs):
package com.blah;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
The compilation works, this class appears to be in the build/classpath so I don't understand why Gradle-Spring-Boot is not finding it. I have also tried explicitly identifying the class with the same result.
Unfortunately I find little documentation about multi-project gradle builds so I suspect that is part of the problem. Hopefully someone here can point me in the right direction as to what is wrong.
Thanks
I discovered the issue here. We have custom code in /buildSrc that is apparently causing this.

How to access version property from BOM with Gradle?

I'm migrating a small multi-module project from Maven to Gradle, to evaluate and (hopefully) to learn something.
subprojects {
group = "com.company.project-name"
apply plugin: "java"
repositories {
mavenCentral()
}
dependencies {
implementation platform("org.springframework.boot:spring-boot-dependencies:2.5.2")
compileOnly("org.projectlombok:lombok")
annotationProcessor("org.projectlombok:lombok")
}
}
This is what I have so far. Despite a small problem it's already working. As you can see, I'm importing org.springframework.boot:spring-boot-dependencies as platform dependency / BOM (Bill of Materials). As far as I understand this is equivalent to a Maven parent. spring-boot-dependencies already defines almost everything I'm using in this project. However, I'm also using Lombok. Luckily Spring takes care of that too.
This work as expected for the compileOnly dependency org.projectlombok:lombok. The problem is the annotationProcessor. Compiling the project results in an error:
[...]
Execution failed for task [...].
> Could not resolve all files for configuration [...].
> Could not find org.projectlombok:lombok:.
Required by:
project [...]
[...]
If I change it to something like this:
annotationProcessor("org.projectlombok:lombok:1.18.20")
... it works. But I want Gradle to use the version definition for Lombok from spring-boot-dependencies, because I don't want to define it again myself. With Maven I could just use the Maven property lombok.version. So I also tried something like this:
annotationProcessor("org.projectlombok:lombok:${lombok.version}")
Unfortunately, this result in another error:
A problem occurred evaluating root project [...].
> Could not get unknown property 'lombok' for object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
What is the Gradle equivalent to access a defined version property from a platform dependency / BOM?
Have you tried this:
annotationProcessor platform("org.springframework.boot:spring-boot-dependencies:2.5.2")
Make sure the annotationProcessor is on the top of the dependencies.
dependencies {
annotationProcessor platform("org.springframework.boot:spring-boot-dependencies:2.5.2")
annotationProcessor("org.projectlombok:lombok")
implementation platform("org.springframework.boot:spring-boot-dependencies:2.5.2")
compileOnly("org.projectlombok:lombok")
}

Spring Boot + Kotlin + Gradle - Error: Main method not found in class

I'm learning spring boot with Kotlin (since I come from Android with Kotlin). I set it up with gradle. In my local machine everything works just fine. But I'm having a few issues while trying to deploy it to Heroku.
This is the error I'm getting:
Error: Main method not found in class com.markoid.packit.PackitApplication, please define the main method as:
2021-07-01T20:58:51.075484+00:00 app[web.1]: public static void main(String[] args)
2021-07-01T20:58:51.075581+00:00 app[web.1]: or a JavaFX application class must extend javafx.application.Application
I read on other posts that I need to add system.properties file in the root, so I did, but nothing changes.
system.properties
java.runtime.version=11
And this is my build.gradle.kts
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "2.5.1"
id("io.spring.dependency-management") version "1.0.11.RELEASE"
kotlin("jvm") version "1.5.10"
kotlin("plugin.spring") version "1.5.10"
}
group = "com.markoid"
version = "1.0.0-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11
repositories {
mavenCentral()
}
dependencies {
// Spring Boot Core
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-mail")
implementation("org.springframework.boot:spring-boot-starter-data-mongodb")
// Joda Time library
implementation("joda-time:joda-time:2.10")
// Json Web Token
implementation("io.jsonwebtoken:jjwt-impl:0.11.1")
implementation("io.jsonwebtoken:jjwt-api:0.11.1")
implementation("io.jsonwebtoken:jjwt-jackson:0.11.1")
// Serializers
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
// Documentation
implementation("io.springfox:springfox-swagger2:2.6.1")
// Kotlin related
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
// Testing Frameworks
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "11"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
tasks.withType<Jar> {
manifest {
attributes["Main-Class"] = "com.markoid.packit.PackitApplication"
}
}
My app file is as simple as this:
#SpringBootApplication
class PackitApplication
fun main(args: Array<String>) {
runApplication<PackitApplication>(*args)
}
Does someone know what I'm missing? This is the first project on spring I'm trying to deploy on heroku, so please bare with me.
Thank you in advance.
I've faced with the same issue. My problematic configuration is:
Kotlin 1.5.21
Spring boot 2.5.2
Gradle 7.1.1
The problem was that in IDEA it can be run, but cannot not using gradlew command line. I went and checked all old projects. They were built and run without any problem. The difference was in versions. All my previous project had lower versions in all positions I mentioned above. So I suggested that the problem was in the version, but what tool it was? Kotlin, Spring, Gradle? I have not yet found the guilty (and no time to go into deep of this problem now), but I found a solution.
If you open your jar file in any archiver (eg. WinRAR) and look at the MANIFEST.MD you will see a line starting with 'Start-Class', there is your main class and it must end with 'Kt' suffix, for example
Start-Class: me.sigest.fiveplus.FiveplusApplicationKt
In my failed jar it was not. To fix it I changed the code in build.gradle.kts file and set
springBoot {
mainClass.set("com.example.MyMainClassKt")
}
Despite the fact that in reality my class is called MyMainClass (without suffix Kt) and it helped
P.S. all my old boot jars contain the correct name of main class with Kt. I suppose the problem is in Gradle
I just had to a few things to make it work:
In the build.gradle.kts, I removed the tasks with type jar, and added this:
springBoot {
mainClass.set("com.markoid.packit.PackitApplicationKt")
}
I needed to add a Procfile, with the following:
web: java -Dserver.port=$PORT $JAVA_OPTS -jar build/libs/packit-1.0.0-SNAPSHOT.jar
Such file will tell heroku the specific command I want to be executed to run the generated jar.
Have you tried changing the main method like it is being suggested in the error message, i.e. public static void main(String[] args)

Replicating Maven "dependencyManagement" tag from inside Gradle build

I am trying to follow this Spring Boot/Vaadin guide however I'm using Gradle, not Maven.
At the very top of that guide they say to use the following Maven XML:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-bom</artifactId>
<version>10.0.11</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
However I don't see a dependencyManagement task available via Gradle. So I ask: how do I replicate the same behavior as the <dependencyManagement/> XML element above over in "Gradle land"?
Update: current attempt
dependencyManagement {
imports {
mavenBom 'com.vaadin:vaadin-bom:10.0.11'
}
}
Only problem with this is that when I add it to my build.gradle and then run ./gradlew clean I get the following Gradle error:
"Could not find method dependencyManagement() for arguments..."
This should give you a working build:
plugins {
// the Gradle plugin which provides the “dependencyManagement” block
id 'io.spring.dependency-management' version '1.0.6.RELEASE'
// add Java build functionality to be able to follow the Vaadin guide
id 'java'
}
dependencyManagement {
imports {
// the Maven BOM which contains a coherent set of module versions
// for Vaadin dependencies
mavenBom 'com.vaadin:vaadin-bom:10.0.11'
}
}
repositories {
// find dependency modules on Maven Central
mavenCentral()
}
dependencies {
// the dependency module you need according to the Vaadin with
// Spring Boot guide; the version of the module is taken from the
// imported BOM; transitive dependencies are automatically taken
// care of by Gradle (just as with Maven)
compile 'com.vaadin:vaadin-spring-boot-starter'
}
Run ./gradlew dependencies --configuration compileClasspath to see that all dependencies are available on your Java compile classpath now.
Edited to reply to the question in the comments: indeed, the import of the BOM leads to a slightly different set of dependencies than would be used without it. You can see the dependencies difference like so:
./gradlew dependencies --configuration compileClasspath > with-BOM.txt
Remove the dependencyManagement block and add a version to the single dependency: compile 'com.vaadin:vaadin-spring-boot-starter:10.0.11'
./gradlew dependencies --configuration compileClasspath > without-BOM.txt
diff -u with-BOM.txt without-BOM.txt
You can see slight differences like org.webjars.bowergithub.webcomponents:webcomponentsjs:1.2.6 being used with the BOM and version 1.2.2 without it. The reason for that can be found in the BOM where version 1.2.6 is defined and where the authors also mention the reason for that: “Transitive webjar dependencies, defined here for repeatable builds”
Generally maven dependencyManagement tag is used to import bom or control transitive versions.
Gradle does that with platform component, like below example.
dependencies {
implementation platform('com.vaadin:vaadin-bom:10.0.11')
implementation ('com.vaadin:vaadin-core')
}
This does not force you to depend on spring plugin for importing bom.

liquibase.integration.spring.SpringLiquibase is available from 2 locations error in spring boot

I'm trying to integrate spring boot with liquibase, but when I run the application it throws the following error:
An attempt was made to call the method liquibase.integration.spring.SpringLiquibase.setLiquibaseSchema(Ljava/lang/String;)V but it does not exist. Its class, liquibase.integration.spring.SpringLiquibase, is available from the following locations:
jar:file:/C:/Users/Dev/.gradle/caches/modules-2/files-2.1/org.liquibase/liquibase-core/3.5.5/c65051f327382018bd09c30380f25eac96f210da/liquibase-core-3.5.5.jar!/liquibase/integration/spring/SpringLiquibase.class
It was loaded from the following location:
file:/C:/Users/Dev/.gradle/caches/modules-2/files-2.1/org.liquibase/liquibase-core/3.5.5/c65051f327382018bd09c30380f25eac96f210da/liquibase-core-3.5.5.jar
Action:
Correct the classpath of your application so that it contains a single, compatible version of liquibase.integration.spring.SpringLiquibase
It looks like that the problem is given by spring-boot-starter-data-jpa, as soon as I remove the dependency, the application runs fine. This is my full dependency list, but I would also need JPA to write my persistence classes.
dependencies {
compile('org.springframework.boot:spring-boot-starter-actuator')
compile 'org.springframework.boot:spring-boot-starter-web'
runtime('org.postgresql:postgresql:42.2.5')
compile 'org.webjars:bootstrap:4.1.3'
compile 'org.webjars:webjars-locator-core'
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile("org.hibernate:hibernate-entitymanager:4.3.4.Final")
compile("org.hibernate:hibernate-validator:6.0.16.Final")
compile ("org.hibernate:hibernate-core:5.4.1.Final")
testCompile 'org.springframework.boot:spring-boot-starter-test'
compile("org.liquibase:liquibase-core:3.5.5")
liquibaseRuntime 'org.liquibase:liquibase-gradle-plugin:2.0.1'
liquibaseRuntime 'org.liquibase:liquibase-groovy-dsl:2.0.2'
liquibaseRuntime "org.liquibase:liquibase-core:3.5.5"
liquibaseRuntime 'org.postgresql:postgresql:42.2.5'
}
Any idea why there's a mismatch?
Thanks in advance
Remove the version from your configuration:
compile("org.liquibase:liquibase-core")
Let Spring Dependency Management take care of that for you.
I solved it in my maven project just by removing the Liquibase version in the POM
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
Leave it this way without the version and Spring takes care of the rest.
In my case upgrading to using both Spring Boot 2.1.0.RELEASE and org.liquibase:liquibase-core:3.6.3 solved the issue entirely.
Sounds like two different dependencies include a duplicate jar.
There seems to be a plugin that manages dependencies in Gradle, take a look here.

Resources