Basic "Hello World" Spring Boot application in IDEA doesn't work - spring-boot

I can't decide if there is a problem with the instructions in the spring.io tutorial or if there's something wrong with IDEA. Some help would be nice.
I'm following a guide at spring.io to create a simple blog application. I've used the spring initializr to create the application as directed (using Gradle, JDK 1.8, Kotlin) and I cannot run the application from a Spring Boot Run/Debug Configuration. It works only when I run the gradle "bootRun" task, but running through IntelliJ yields a Whitelabel Error Page.
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Additionally, the Spring Boot output in my console shows that the MustacheAutoConfiguration class could not find the /templates/ folder in my classpath.
2019-11-19 13:06:07.136 WARN 11840 --- [ restartedMain] o.s.b.a.m.MustacheAutoConfiguration : Cannot find template location: classpath:/templates/ (please add some templates, check your Mustache configuration, or set spring.mustache.check-template-location=false)
My Spring Boot Run/Debug configuration for BlogApplication has "Use classpath of module: blog.main".
Is there something else I'm missing here?

Did run the application after cloning from the github source. It runs just fine from intellj idea. Tested on JDK 13, 11 and 8
and the configuration for Boot run from intellj idea is bellow.
So I would suggest checking your gradle configuration of intelljidea.

This appears to be a known issue at the moment. See: https://youtrack.jetbrains.com/issue/IDEA-221673

Related

Maven install command with environment variables file

Is there any way to execute the environment variables file .env along with maven commands such as mvn clean install or mvn clean deploy. The main idea behind the concept that I'm looking for similar kind of solution:
mvn clean install -DenvFile=/path/<filename>.env
OR
mvn clean deploy -DenvFile=/path/<filename>.env
OR
mvn clean package -DenvFile=/path/<filename>.env
Note: Not trying to produce the environment specific builds. In dev environment, my intention to run the junit tests with all the
environment variables configured from <filename>.env.
where, the above maven commands should set all the environment variables from <filename>.env and then execute the maven plugins. In IntelliJ, there's a envFile plugin which exactly do the same.
Don't want to have environment specific properties dev|staging|prod.properties in my project because it's messy and hard to manage. I'd rather prefer to have one single environment specific file filename.env which contains all the dynamic/changeable properties.
application.properties
spring:
cloud:
config:
uri: http://config-service:${CONFIG_SERVICE_PORT}
fail-fast: true
password: ${CONFIG_SERVICE_PASSWORD}
username: user
Environment File: .env
CONFIG_SERVICE_PORT=8080
CONFIG_SERVICE_PASSWORD=123
Now when I deploy the application in different environments like AWS, GCP and Azure. All I need to change the environment variables in the .env file and run the application java -DenvFile=/path/<fileName>.env -jar application.jar and it will do the magic.
My problem is related with maven-sure-fire plugin for testing in dev-mode, which require these environments variables for spring context.
Any help would be appreciated.
Ok from your comments it seems like you're looks for two different solutions:
Run the application in different environments with java -DenvFile=/path/<fileName>.env -jar application.jar
Solution for running tests.
These are different issues I'll try to address both
Issue 1
When you run java -jar this means that the artifact is already assembled (with the help of spring boot maven plugin as far as I understand).
This jar is a ready to go spring boot application and maven is basically irrelevant here - maven is a build system, spring is a runtime framework and we're talking about the runtime.
Spring boot has a lot of ways to achieve what you want. A "Native" spring boot way which is close to your situation is running the application with "--spring.config.location=file:// with all the required configurations
It looks like this (see here for complete documentation):
java -jar application.jar --spring.config.location=myprops.properties
Even if you have some properties defined in src/main/resources/application.properties this method allows to override them effectively providing a way to run different configurations in different environments.
This has an advantage over the .env files because it can run in the same way in all the OS-es, even Windows ;) Since Java is OS independent - I believe its the best you can achieve.
Of course you can wrap the java -jar line in some kind of bash script and load / execute a series of export commands before running the jvm, but again, its less "spring-y" way.
Issue 2
Maven runs the tests (unit/integration) in a way that spring boot maven plugin is irrelevant. Its all about surefire/failsafe and spring boot testing framework.
I'll assume you're asking about integration tests because I believe this is all irrelevant for unit tests, since those should not require any environment variables at all and should be run without spring at all (junit/mockito should do the job)
I'll also allow myself to keep the assumption that the way of overriding/configuring the spring boot application via yaml or properties file is better than .env and will provide spring test configuration solution here:
With these assumptions you can create a yaml file in the following path: src/test/resources/application-test.yml
This file can contain configurations relevant for tests and will override anything written in src/main/resources/application.yml. Note, since application-test.yml resides in test sources, spring boot maven plugin won't package it into the application.
Depending on the exact way of doing integration tests you might consider also using #TestPropertySource annotation to provide the custom properties/yaml file that doesn't follow spring boot's default convention. Its especially useful for spring driven tests that do not bootstrap with the spring boot full fledged support (read the tests that use junit's spring runner but don't have annotation #SpringBootTest)
Another possibly useful annotation is #ActiveProfile("myprofile"). This will cause spring boot tests to automatically load file src/test/resources/application-myprofile.yml (or application-myprofile.properties)
Last but not least I'll refer the second comment with "dev/prod/staging/properties" in the source.
When it comes to tests - there should be only one file application-test.yml. However note that when you're using yaml, its possible to define configurations for many spring boot profiles in the same file:
# default value
foo:
bar: 1
---
spring:
profiles: staging
foo:
bar: 2
---
spring:
profiles: prod
foo:
bar: 3
Some relevant SO thread

Spring Boot Flyway migrations not executed, SQL files are in JAR

I have a Spring Boot application using Flyway Migrations. Everything runs fine, from:
within IntelliJ
from the terminal on my macbook
With 'fine' I mean, migration files are found, which are placed in src/main/resources and end up in the Spring Boot executable jar.
However, when I run the jar from the commandline on Centos 6.8, Flyway is unable to find the migration files.
Any ideas?
Using Java 8.
The easiest way to resolve it is to open at your logger the package org.flywaydb to loglevel DEBUG and retry. For sure you'll find the initial clue.
Good luck

tomcat7-maven-plugin to deploy spring boot with appropriate spring profile selected

My goal is to be able to use the tomcat-maven plugin to deploy my spring boot application from the command line where an argument is supplied that tells spring which profile to use like this:
mvn tomcat7:deploy -Dspring.profiles.active="dev"
I've tried several different things such as the solution described here but the default application.properties is still always selected.
The only way that I've been able to get the application-dev.properties selected is by using
mvn spring-boot:run -Dspring.profiles.active="dev"
But we don't want to have tomcat packaged in our war
I'm new to maven and spring boot and I've been spinning my wheels for the better part of a a day now so any advice would be appreciated.
Consider using MAVEN_OPTS environment variable to set VM argument. (Linux/osx) example you would need to execute before your maven goal:
export MAVEN_OPTS="-Dspring.profiles.active=dev"
I found out the issue and I was able to get the correct profile selected using
export SPRING_PROFILES_ACTIVE=dev. The problem that I was having was when I was starting my local tomcat server through the eclipse UI my environment variables were being ignored. When starting tomcat through startup.bat the environment variable gets used and spring uses the correct profile.

Spring Tool Suite finds spring-boot integration test configuration and does not start main application

I have a little struggle with Spring Tool Suite in combination with spring-boot.
I created a custom Maven spring-boot-web-application including several JUnit tests, one of this test is an integration test which has a configuration for the testapplication.
If I want to start the spring-boot-web-application via Spring Tool Suite ( run as -> Spring Boot Application ) the application does not start because both configurations ( src/main/java, src/test/java ) are found and conflict each other.
As soon I remove the test resources from the buildpath the application starts as expected.
Is there any setting in Spring Tool Suite to prevent the test resources are added to the classpath when starting the spring-boot-web-application?
Thank you in advance!
STS 3.6.4 has a bug in it that causes the classpath for "Run As >> Spring Boot App" on maven projects to include 'test stuff' (source folders and jar dependencies) to be on the runtime classpath.
The bug is a regression as it did not exist in 3.6.3. The bug is fixed already in master and the fix will be part of STS 3.7.0. You can get this fix today by updating your STS installation from the nightly update site:
http://dist.springframework.org/snapshot/IDE/nightly/
Open "Help >> Install New Software" and paste the above link in the "work with" field and then install the "Core" pieces. The installer will inform you that you already have these and will perform an upgrade instead.
After this upgrade is succesful, "Run As >> Boot App" should no longer have test stuff on the runtime classpath.

spring boot tomcat termination

I have exactly the same issue like that one: Terminating mvn spring-boot:run doesn't stop tomcat
The answer there says that it only happens on Windows but it's not actually true. I'm running spring boot on OSX with Intellij and when I stop the spring boot application the embedded tomcat is still running. The is the simple sample app from spring boot tutorial. Any solutions?
i have exactly the same issue within intellij on MAC (spring boot 1.1.6.RELEASE).
i worked around it by using spring boot actuator which offers a rest endpoint (Post) to shutdown the app:
localhost:port/shutdown
this can be called by commandline: e.g. curl -X POST localhost:port/shutdown
to enable spring boot actuator add the following compile dep:
org.springframework.boot:spring-boot-starter-actuator
i created a gradle task bootStop which does run this cmd for me.
you could do the same in maven or
you can just call it from cmd line (also trough the intellij terminal)
Especially if you want to use debugging, you should wrap the curl cmd given above in a gradle/maven task.
See working example (gradle) here
Here is a maven example for spring boot actuator to configure HTTP endpoint to shutdown a spring boot web app:
1.Maven Pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2.application.properties:
#No auth protected
endpoints.shutdown.sensitive=false
#Enable shutdown endpoint
endpoints.shutdown.enabled=true
All endpoints are listed here:
3.Send a post method to shutdown the app:
curl -X POST localhost:port/shutdown
I have met the same issue and as result I had to review all solutions on this page and related one. No one is good for me. That is why I have made small research and it is appeared that problems with captured TCP port happen just because neither Gradle nor mvn knows nothing about child manipulation with TCP port.
So instead of killing process just use command:
$ gradlew –stop
(I hope the same exists for mvn)
This command gracefully closes daemons started by Gradle and frees captured by Tomcat ports.
Following the previous answer, this property is deprecated now, so replace it with:
management.endpoint.shutdown.enabled=true
A simpler solution is to create a "Spring Boot" configuration and use that to start your app instead of the "Gradle" configuration. The "Spring Boot" configuration does not experience this issue.

Resources