Can I pass an internal Spring Boot variable to gradlew? - java

I have a question. In my app, I do have several configurations:
application-prod.properties
application-test.properties
application-dev.properties
and the main file:
application.properties
Containing one line:
spring.profiles.active=test
To build and run the app I am using ./gradlew buildNeeded
Can I somehow pass the properties suffix: test, prod, dev so it is used in the build process, so I can make different bash scripts to run the installation process on test and prod servers?
I am looking for something like ./gradlew buildNeeded --spring.profiles.active=test or anything that will work...

You can achieve that using spring-gradle-plugin.
From plugin documentation Passing arguments to your application
Like all JavaExec tasks, arguments can be passed into bootRun from the
command line using --args='' when using Gradle 4.9 or
later. For example, to run your application with a profile named dev
active the following command can be used:
./gradlew bootRun --args='--spring.profiles.active=dev'

You can use project properties:
task buildNeeded {
doLast {
def springProfile = project.properties.getOrDefault('spring.profiles.active', 'test')
println springProfile
}
}
Then you can run the project with
./gradlew buildNeeded -Pspring.profiles.active=test

Related

Pass gradle command line arguments to application.properties

I have a Spring Boot Gradle application and many MySQL servers and databases.
In different scenarios, I want to start the application with different databases or create them if they do not exist. I want to use this mechanism with command line arguments.
The URL for database is stored in application.properties file of Spring:
spring.datasource.url=jdbc:mysql://localhost:3306/mydb1?createDatabaseIfNotExist=true&useSSL=true
I want to run gradle with command line arguments that will apply to the application.properties file so in my head will be something like this.
application.properties :
spring.datasource.url=jdbc:mysql://${linkNewDB}?createDatabaseIfNotExist=true&useSSL=true
And to run the program as :
gradle bootRun -Pargs=--linkNewDB="someNewDB:3309"
Does anybody know how can I achieve this mechanism? I tried different options but none of them worked. Thanks!
How about changing the whole URL, like this:
gradle bootRun --args='--spring.datasource.url=jdbc:mysql://someNewDB:3309?createDatabaseIfNotExist=true&useSSL=true'
reference: https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/htmlsingle/#running-your-application.passing-arguments

Specifying a logback config file via maven command in jenkinsFile

I use a custom logback.xml to configure logging. Usually I pass it in via the logging.config property in application.properties to the spring application, however I now need to specify a path to it so it can be picked up by a non-spring mvn module.
This command works fine in my intelliJ run configuration:
verify "-Dlogback.configurationFile=${ALLUSERSPROFILE}/myPath/logback.xml" -f pom.xml
I thought that transferring this to my jenkinsFile would be trivial:
withMaven(mavenSettingsConfig: 'nexus-maven-settings') {
withNPM(npmrcConfig: 'nexus-npm-ro-settings') {
powershell 'mvn verify "-Dlogback.configurationFile=${ALLUSERSPROFILE}/myPath/logback.xml" -f webApp/com.pilz.ie.s30.automation/pom.xml'
}
}
but my logbackfile isn't working. I suspect it is a powershell issue with the single quote, double quotes or the Env var, but for some reason the logback file just isn't being picked up.
Any help appreciated!

Externalizing Run configurations for Grails app

Is there a way to externalize the run config for per environment configurations with Grails 3 applications?
I am aware that there are run config arguments that allow one to run their application under a dev, prod, test, etc environment, but I was wondering if there is a variable, for example "grails.env" that I can change in a properties, YAML, config, or other file that can be read at run time that will do this for me.
This is just to avoid confusion between the application being tested and run in one setting/environment(physical environment like my local machine), then being given to another individual or team to run elsewhere.
The goal is to configure or set this variable so the run team/individual wont need to know or change the run commands.
Im aware of how to configure the environment with the command line, and within intelliJ and Eclipse. I'm wondering if there is a way to default this in perhaps a file that is read instead.
Thanks
I'm not to sure what is confusing you here but let me try and see if I can point you in the right direction
From the documentation here: http://docs.grails.org/latest/guide/conf.html#environments your application can be delivered as a package war file to the target user to have tested, and the war file can be created with any of of the environment configurations
grails test war
Since the command is can be run in the console, you could run with system properties like this:
grails $ENVIRONMENT war
Hope this helps
Update 2
By default the grails run-app runs with the dev environment, but you can force an environment by doing
grails $env run-app
If you want some default configurations to be run when you use the run-app command, then you should make sure that configuration is not in the environment block in either application.yml or application.groovy
Example of configuration in the environment block:
-----------------------------------------------------
environment{
development{
appConfig{
ishybrid = true
}
}
}
Example of configuration not in any environment block:
-------------------------------------------------------
appConfig{
ishybrid = true
}
environment{
development{
//other configs
}
}
So basically depending on what you exclude from the environment block configuration is what will be configured as the default configuration for your application to run.
Hope this helps better?

Maven run configuration doesn't pick up active profile while Spring run configuration does

My Spring run configuration is just the default with the following the VM options:
-Dspring.profiles.active=local
My Maven run configuration is the defaults with the following in the command line:
spring-boot:run
and the following in VM options:
-Dspring.profiles.active=local
When I run the maven one it doesn't pick up on a profile and instead uses default:
No active profile set, falling back to default profiles: default
With the Spring configuration I have no issues, the problem is with how I need to deploy it, it uses a maven command, so I can't have this failing and I don't really understand why it's happening. There really isn't anything fancy is this projects. It's your basic micro service.
Just in case it's needed. The root 'Application' file only has the following:
#SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Link to the Maven run config. It is all defaults outside of what is pictured. https://imgur.com/a/GGiwimQ
Adding the following to the command line arguments seemed to fix it:
-Drun.jvmArguments=-Dspring.profiles.active=local
Although I understand why it worked it doesn't explain why this happened in the first place. I will update this answer if I ever find out the true reason.
create
application.properties
file in src/main/resources if it doesnt exist and add
spring.profiles.active=local

Spring boot + Gradle properties file

I have two properties files in src/main/resources application-dev.properties and application-prod.properties.
When I run my application with java -jar -Dspring.profiles.active=dev it picks the correct properties file and my application is running.
However when I use gradle -Dspring.profiles.active=dev test, the properties are not set from the specified profile.
I also created an application.properties file containing spring.profiles.active=dev.
When I compile and run with java -jar test.jar it works as expected but when I use gradle test the properties are ignored.
There are two JVMs involved, one running Gradle and one running your test. When you run gradle -Dspring.profiles.active=dev test you are setting a property on the JVM running Gradle, not the JVM running your test. Gradle doesn't automatically copy system properties from its JVM to the JVM it spawns. This topic at the Gradle forums explains how to set properties on the JVM running your test, but in short you'll need something like this in your build.gradle:
tasks.withType(Test) {
systemProperty 'spring.profiles.active', 'dev test'
}
If you've set the active profile as a system property you can use this:
tasks.withType(Test) {
systemProperty 'spring.profiles.active', System.getProperty('spring.profiles.active')
}
To copy all system properties:
tasks.withType(Test) {
systemProperties = System.getProperties()
}

Categories