Using Gradle property expansion in kotlin/spring boot - spring-boot

I am currently building a Kotlin, Spring Boot service using gradle as the build tool. I am attempting to automatically expand properties found in my application.properties file, using the steps found here:
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-properties-and-configuration.html#howto-automatic-expansion-gradle
My versions are as follows:
- kotlin: 1.1.4-3
- spring boot: 1.5.6.RELEASE
- gradle: 3.5.1
When I run a ./gradlew bootRun, I get the following error:
java.lang.IllegalArgumentException: Could not resolve placeholder 'myServiceName' in value "${myServiceName}"
Followed by:
java.lang.IllegalStateException: LifecycleProcessor not initialized - call 'refresh' before invoking lifecycle methods via the context: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#510aeb93: startup date [Fri Sep 15 10:59:51 AEST 2017]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext#68edf5bb
build.gradle:
apply plugin: 'kotlin'
apply plugin: 'kotlin-spring'
apply plugin: 'org.springframework.boot'
processResources {
filesMatching('application.properties') {
expand(project.properties)
}
}
gradle.properties:
myServiceName=potato-service
application.properties:
info.app.name=${myServiceName}
These errors appear after the app has started, and spring is trying to load the property file.
The interesting thing is that if I change the variable that I am trying to substitute in the application.properties, to myServiceName123 for example, gradle fails at the processResources stage.

So, there was a small part of my build.gradle that I did not include above as I did not know about it:
bootRun {
addResources = true
}
According to the Spring Boot Docs having the addResources flag set to true will ignore the application.properties file created in the processResources step, and instead use the one in your projects sources. This is to allow you to dynamically change the file without needing to restart the application.
The correct fix for this (if you need variable expansion when running with the bootRun task) is to set:
bootRun {
addResources = false
}
Otherwise, if you just need expansion when building your jar, leaving this flag as true should be fine.

Related

Is io.spring.dependency-management plugin required when using Spring Boot 2.3+ and Spring Cloud?

I'm using Gradle 6.6 to build my Spring Boot app. According to this post, the io.spring.dependency-management plugin is no longer needed since Gradle 5+ supports BOM files.
However, I receive the following error if I remove the plugin:
Could not run phased build action using connection to Gradle distribution 'https://services.gradle.org/distributions/gradle-6.6.1-bin.zip'.
Build file 'C:\my-app\build.gradle' line: 14
A problem occurred evaluating root project 'my-app'.
Could not find method dependencyManagement() for arguments [build_6e8ejdhnd2no2m9jw221sctmn3$_run_closure2#432e46e2] on root project 'my-app' of type org.gradle.api.Project.
Line 14 of my build.gradle file is referenced in the above error. Here are lines 14-18:
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:Hoxton.SR8"
}
}
Is there another way to specify the required dependencies for Spring Cloud without using io.spring.dependency-management plugin?
dependencyManagement() is provided exclusively by the io.spring.dependency-management plugin. Which means you cannot use it if you don't use the plugin.
And in that case you have to use the gradle's platform capability.
In the post you linked there's an example of that.
To fix your build, remove the dependencyManagement part and add
implementation platform("org.springframework.cloud:spring-cloud-dependencies:Hoxton.SR8")
to your dependencies { }
Reference: https://docs.spring.io/dependency-management-plugin/docs/current/reference/html/#dependency-management-configuration-dsl

Gradle 'war' plugin how to change name of an archive

How can I change the name of war?
I already tried (I found these params in documentation https://docs.gradle.org/4.10.2/dsl/org.gradle.api.tasks.bundling.War.html)
war {
baseName = 'service'
archiveName 'service.war'
}
However, this is not working. I am still getting a name with a snapshot version.
./build/libs/search-0.0.1-SNAPSHOT.war
I am using Gradle 4.10 and Spring Boot 2.1.2.RELEASE.
Please refer to this documentation : Spring Boot Gradle reference
To sum up: when applying the Spring Boot gradle plugin together with war plugin, the war task is disabled by default and "replaced" by the SpringBoot bootWar task.
So if you want to configure the war artefact, you will need to configure the bootWar task instead of base war task :
bootWar {
baseName = 'service'
archiveName 'service.war'
}
Additional notes:
in Gradle 5.x , archiveName has been deprecated, and you should use archiveFileName instead
if you set the archiveName property you don't need to set baseName property
M. Ricciuti answer is correct, with the caveat that even though archiveName has been deprecated in Gradle 5.x, Spring Boot is still using it in 2.1.6.RELEASE. For example, if the bootWar task was configured with the new archiveFileName property like this:
bootWar {
archiveFileName 'service.war'
}
you will get this error:
Could not find method archiveFileName() for arguments [service.war] on task ':bootWar' of type org.springframework.boot.gradle.tasks.bundling.BootWar.
Use archiveName for now. See Spring BootWar class Java doc for details. They may add archiveFileName in the future.
bootWar {
archiveFileName.set 'service.war'
}
codemule - answer is correct, with a different error message when archiveFileName was used in bootWar task. I am using Gradle 6.5.1.
With the below bootWar task
bootWar {
archiveFileName 'bst.war'
}
I got the error message
A problem occurred evaluating root project 'example'.
> No signature of method: build_1z1dezuc71i4g9wsz51um0q6o.bootWar() is applicable for argument types: (build_1z1dezuc71i4g9wsz51um0q6o$_run_closure1) values: [build_1z1dezuc71i4g9wsz51um0q6o$_run_closure1#7abe6e]
It disappeared when bootWar task was configured with archiveName
bootWar {
archiveName 'example.war'
}

Inject Gradle properties into Spring Boot application.yml, not working in IntelliJ IDEA

I've managed to inject the Gradle proj.ver into application.yml and after that injected it into service application.
My application.yml looks like this:
project:
version: ${version}
But it works only if I started the app from cli with:
gradle bootRun
If I'm trying to start the app from IntelliJ, it didn't work and it failed with:
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'version' in value "${version}"
I read all the answers from Stackoverflow and they suggested two solutions:
Use spring profiles
Modify run configuration and run before launch the gradle task: processResources
I'd prefer something like a default value for proj.ver when I'm running from IntelliJ. Is that possible? Or are any better solutions for this situation ?
Thanks
As M. Deinum said above in the comment, I managed to run the app from IntelliJ, but now the gradle bootRun started to fail with:
Caused by: groovy.lang.MissingPropertyException: No such property: unknown for class: SimpleTemplateScript2
After some more research it seems that ${version?:unknown}(with the question mark) it works either from the IDE or from cli.
I've updated the response, in order for others to know how to inject Gradle build info into Spring-boot:
1) Tell Gradle to pass the build data towards a Spring yml file like this:
processResources {
filesMatching('appInfo.yml') {
expand(project.properties)
}}
2) The appInfo.yml will look like:
project:
version: ${version?:unknown}
3) Inject the version of the build into Spring services like:
#Value("${project.version}")
private String applicationVersion;
Just to complete for Kotlin user, what works for me was :
build.gradle.kts
tasks.processResources { filesMatching("**/application.properties") { expand(project.properties) } }
application.properties
project.version= ${version}
Service.kt
#Value("\${project.version}") lateinit var version: String

How do I run FlyWay clean with Spring Boot?

I'm using Spring Boot and FlyWay together. I added the FlyWay dependency to my Gradle build file like this:
dependencies {
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.postgresql:postgresql:9.4-1202-jdbc42")
compile("org.flywaydb:flyway-core")
testCompile("org.springframework.boot:spring-boot-starter-test")
}
I also added a db/migrations folder with an initial migration file. The migration works as expected. But now I want to clean by using the gradle flywayClean task. However, when I run this, I get an error saying the task can't be found. Is there another way I'm supposed to do this with Spring Boot?
To run gradle flywayClean, you have to apply the plugin: 'org.flywaydb.flyway'
See http://flywaydb.org/getstarted/firststeps/gradle.html

Hot Deployment with Jetty Plugin for Gradle

I am currently using the Jetty plugin for gradle for development:
apply plugin: 'war'
apply plugin: 'jetty'
...
jettyRunWar {
httpPort = 8080
reload = 'automatic'
scanIntervalSeconds = 2
daemon = false
}
jettyRun {
httpPort = 8080
reload = 'automatic'
scanIntervalSeconds = 2
daemon = false
}
However, the hot deployment is not working as expected. When using gradle jettyRunWar, the plugin seems to reload the context when using gradle war, but nothing changes really. When using gradle jettyRun, the reloading works, but JSF is no longer working:
Could not instantiate listener com.sun.faces.config.ConfigureListener: java.lang.ClassNotFoundException: com.sun.faces.config.ConfigureListener
AnnotationConfigurator does not found classes for annotations in /WEB-INF/classes/ . This could happen because maven jetty plugin is used (goal jetty:run). Try configure org.apache
.myfaces.annotation.SCAN_PACKAGES init parameter or use jetty:run-exploded instead.
Any ideas how to get one of these options to work? Setting the mentioned parameter leads just to more exceptions.

Resources