Spring Boot Profile Gradle - spring-boot

Based on this post, I run my Spring Boot application with
./gradlew bootRun -Dspring-boot.run.profiles=foo
A component with the profile doesn't run. And I try to verify the active profile with the following code in the root Application class
#Autowired
private Environment environment;
#PostConstruct
void postConstruct(){
String[] activeProfiles = environment.getActiveProfiles();
log.info("active profiles: {}",
Arrays.toString(activeProfiles));
}
The log message output is blank.
What is missing?

-Dspring-boot.run.profiles=foo only works with maven. So it will not work with gradle. You can find informaiton on how to bootrun with gradle here.

Related

Changing Spring Boot application version through gradle.properties while using Spring Boot gradle-plugin

I'm using the Spring boot gradle plugin and have put this in my application.yml:
spring:
application:
name: myapp
version: ${version}
I process the resource file for tokens using:
processResources {
filesMatching('application.yml') {
expand(project.properties)
}
}
And I use this annotation in my controller:
public class MyController {
#Value("${spring.application.version}")
private String appversion
...
And it all works, yay! The problem is that I can't figure out what is actually controlling the version because this reports version 0.0.1-SNAPSHOT even though I specify a different version in gradle.properties.
I tried updating the springBoot DSL thusly:
springBoot {
buildInfo {
properties {
version = "${project.version}"
}
}
}
But it has no effect. Could someone help me understand the proper way to increment/manage the version using the Spring Boot gradle plugin?
As said in my comment, the way you have set the version in gradle.properties and how you configured the application.yml is correct.
I guess you still have a version property defined in your main build.gradle, which overrides the value set in the gradle.properties with value 0.0.1-SNAPSHOT

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

WebTestClient does not work when using spring-webflux

I'm using Spring webflux via Spring boot 2.0.0.M3. Below is the dependencies of my project,
dependencies {
compile 'org.springframework.boot:spring-boot-starter-actuator',
'org.springframework.cloud:spring-cloud-starter-config',
'org.springframework.cloud:spring-cloud-sleuth-stream',
'org.springframework.cloud:spring-cloud-starter-sleuth',
'org.springframework.cloud:spring-cloud-starter-stream-rabbit',
'org.springframework.boot:spring-boot-starter-data-mongodb-reactive',
'org.springframework.boot:spring-boot-starter-data-redis-reactive',
'org.springframework.boot:spring-boot-starter-integration',
"org.springframework.integration:spring-integration-amqp",
"org.springframework.integration:spring-integration-mongodb",
'org.springframework.retry:spring-retry',
'org.springframework.boot:spring-boot-starter-webflux',
'org.springframework.boot:spring-boot-starter-reactor-netty',
'com.fasterxml.jackson.datatype:jackson-datatype-joda',
'joda-time:joda-time:2.9.9',
'org.javamoney:moneta:1.0',
'com.squareup.okhttp3:okhttp:3.8.1',
'org.apache.commons:commons-lang3:3.5'
compileOnly 'org.projectlombok:lombok:1.16.18'
testCompile 'org.springframework.boot:spring-boot-starter-test',
'io.projectreactor:reactor-test',
'org.apache.qpid:qpid-broker:6.1.2',
'de.flapdoodle.embed:de.flapdoodle.embed.mongo'
}
The app is running well via ./gradlew bootRun or running main app directly.
However I failed to start integration test due to below error.
Caused by: org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
I'm wondering why WebTestClient still tries to use embedded tomcat even though we are using webflux that uses reactive-netty by default.
Is it something misconfiguration or bug of spring boot test?
Below is code snippet of my test case,
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class NoteHandlerTest {
#Autowired
private WebTestClient webClient;
#Test
public void testNoteNotFound() throws Exception {
this.webClient.get().uri("/note/request/{id}", "nosuchid").accept(MediaType.APPLICATION_JSON_UTF8)
.exchange().expectStatus().isNotFound();
}
}
The error of launching tomcat was caused by test dependency org.apache.qpid:qpid-broker:6.1.2, which depends on javax.serlvet-api:3.1 break the tomcat's startup.
Excluding below useless modules to make tomcat launching again,
configurations {
all*.exclude module: 'qpid-broker-plugins-management-http'
all*.exclude module: 'qpid-broker-plugins-websocket'
}

In Gradle build, start Spring boot application, run tests and then stop the Spring boot application

With my Gradle build I want to start my Spring Boot application, run some tests and then shutdown the Spring boot application. First I try just to start the server and then shutdown, leaving out the tests for now.
Part of my build.gradle file looks like this
bootRun {
systemProperties = System.properties
}
task shutdown(type: org._10ne.gradle.rest.RestTask) {
httpMethod = 'post'
uri = 'http://localhost:8080/shutdown'
}
task integrationTest() {
dependsOn bootRun
finalizedBy shutdown
}
I start the build from the command line like this
gradle integrationTest -Dendpoints.shutdown.enabled=true
The build starts the Spring Boot application but it is not proceeding (of course) to the shutdown task. I can run the shutdown task separately and it will take down the Spring Boot app.
But, how can I get the server to run and shutdown in the same build?
I'm not sure it will work with a task like bootRun, but I think you're looking for something like a ParallelizableTask
Also you would have to pass the --parallel command line option.

IntelliJ can't find javax.servlet.*

I am currently facing a strange issue where IntelliJ can't process my code. Something like this:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterBefore(authenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
...
}
where authenticationFilter returns an instance of GenericFilterBean. This code compiles using Gradle just fine, but IntelliJ complains that my AuthenticationFilter and UsernamePasswordAuthenticationFilter.class don't match the required parameters javax.servlet.Filter and Class<? extends javax.servlet.Filter>.
Upon further inspection, it seems that the class file that defines GenericFilterBean doesn't see the javax.servlet package so in my file, it doesn't know what it is.
Another interesting thing is that spring-ws-core has a dependency on spring-web:4.0.9.RELEASE and my code depends on spring-web:4.3.2.RELEASE, and when I look at the classes inside the 4.3.2 references, it can see javax.servlet, i.e. GenericFilterBean on 4.0.9 breaks, but on 4.3.2 works.
Also, if I do
if (authenticationFilter() instanceof Filter);
if (new UsernameAuthenticationFilter() instanceof Filter);
IntelliJ says I could replace both with != null.
When I run gradlew dependencies, I can see dependencies like org.springframework:spring-beans:4.0.9.RELEASE -> 4.3.2.RELEASE, but IntelliJ displays both in the Gradle Projects view and in the project references.
My project has a multi-project gradle build and the 4.0.9 dependencies are on the subprojects.
What I tried
refreshing the gradle dependencies (through IntelliJ)
invalidating IntelliJ caches
cleaning the project (gradlew clean)
reopening IntelliJ
reinstalling IntelliJ
restarting my computer
Temporary solution
As suggested by #Jens, I added compile('javax.servlet:javax.servlet-api:3.1.0') to allprojects and now IntelliJ can parse it correcly, although it would be better not to have "hacky" dependencies on the build file.

Resources