Spring Boot does not load application.properties and Velocity templates - spring-boot

I have two projects - one is based on the "get started" example, second is from the spring-boot-samples. I build both with Maven and run both from Eclipse. The "spring-boot-samples" project loads application.properties and displays Velocity templates named by the Controller. The "get started" does not.
Same file structure for application.properties (src/main/resources/application.properties) and templates (src/main/resources/templates/**), both with src/main/resources set to "Use as Source Folder" in Eclipse. Same workspace, same JRE.
I compared the .classpath and pom.xml, but found nothing suspicious. Obviously there's a difference, but where do I have to look?
PS: I can load application.properties via #PropertySources, but
that should not be neccessary (see comments there)
is not necessary in the "spring-boot-samples" project
does not help concerning the Velocity templates
Thanks!

To fetch values from application.properties in spring boot, we need to specify some annotation.
application.properties must be in the path src/main/resources
class must contain #RestController annotation
#Value("${name}")
private String name;

Ah, one important difference:
#RestController delivers the response directly, meaning: Instead of resolving the template's name the String is passed to the browser. The reason should be #ResponseBody:
Annotation that indicates a method return value should be bound to the web response body.
Using #Controller instead solves the Velocity problem.
EDIT:
To close this thread: I will continue using #PropertySources to get application.properties, but it does not work without it. Just having application.properties in your classpath is not sufficient.

Related

override spring-boot property in dependency jar file

I have a spring boot project that depends on one of the 3rd party SDK libraries which contains a YAML file with some google cloud URLs.
I want to override those values within my YAML, this works for most of my project but for some reason no luck with this perticular dependency lib.
The Dependency Code
#ConfigurationProperties("google")
public class GoogleProperties {
String url;
..
..
}
Yaml file application-google-prod.yaml
google:
url: some url.
Say this is in a jar called google-client-sdk-1.0.0
My Code
Yaml file application-myapp-prod.yaml
spring:
profiles:
include: google-prod
google:
url: OVERRIDE url.
So I am expecting that the OVERRIDE url should be used when the code in the lib is invoked, but instead it continues to use some url from jar file's yaml.
any pointers?
EDIT
The SDK contains another class
class with the following annotations in the SDK
#Configuation
#PropertySource({"classpath:application-google-prod.yaml})
I think this is forcing SDK to pick the value from the specific YAML ignoring overridden value in the YAML from my app.
Disclaimer:
A is have no mean reproducing your issue, this is just a suggestion.
Notice the absence of #Configuration on GoogleProperties.
You have to either add #Configuration on the properties class:
(impossible in this case) or add #EnableConfigurationProperties(GoogleProperties.class) on top of the class where you want to use the properties.
E.g: Your main class if you want to use them in all the app.
As mentioned in the docs, you can also use:
#ConfigurationPropertiesScan({ "com.google.SDK", "org.acme.another" }) on top of your main class or any #Configuration class where you need those props.
Note: As explained here, the fact that as of spring-boot 2.2 we didn't need any more #Configuration or #EnableConfigurationProperties for the configuration properties feature is outdated.

Spring Boot JUnit and #TestPropertySource using multiple property files

Spring Boot 2.0.3.RELEASE
Have more than one properties file to deal with .. the application.properties and application-DEV.properties
using the annotation #TestPropertySource in a Junit test I can only get it to read one file:
#TestPropertySource("file:C:\\Users\\user\\eclipse-workspace\\one2one_httpCall\\src\\main\\resources\\application-DEV.properties")
works as expected
However I need two properties file I did see the locations option but did not see an example of more than one file .. tried different options but none worked:
#TestPropertySource(locations = "classpath:application-DEV.properties;classpath:application.properties")
Tried a couple of ways I am not posting and even tried using #TestPropertySource twice but error saying u cannot use it twice.
tried using #PropertySource since u can use it twice but did not work since this is a Junit test. Looked at a bunch of questions on stacktrace + others and tried but no luck.
So my question is how to use two properties files via the #TestPropertySource annotation?
If you look inside the definition of #TestPropertySource, you will see that locations is of type String []. Therefore, if you need to pass it multiple values, you must do so with an array:
#TestPropertySource(locations = { "classpath:application.properties", "classpath:application-DEV.properties" })
Also, pay attention to the order in which you declare your properties files. As stated in the TestPropertySource docs:
Each location will be added to the enclosing Environment as its own property source, in the order declared.
So you would probably want to declare your DEV properties after to avoid them being overriden by your production properties.

What is advantage of using #value annotation in Spring Boot

I am new to Spring Boot and I am doing code cleanup for my old Spring Boot application.
Below code is using #Value annotation to inject filed value from properties file.
#Value("${abc.local.configs.filepath}")
private String LOCAL_ABC_CONFIGS_XML_FILEPATH;
My doubt is instead of getting value from properties file, can we not directly hardcode the value in same java class variable?
Example: private String LOCAL_ABC_CONFIGS_XML_FILEPATH="/abc/config/abc.txt"
It would be easier for me to modify the values in future as it will be in same class.
What is advantage of reading from properties file, does it make the code decoupled ?
This technique is called as externalising configurations. You are absolutely right that you can have your constants defined in the very same class files. But, sometimes, your configurations are volatile or may change with respect to the environment being deployed to.
For Example:
Scene 1:
I have a variables for DB connection details which will change with the environment. Remember, you will create a build out of your application and deploy it first to Dev, then take same build to stage and finally to the production.
Having your configurations defined externally, helps you to pre-define them at environment level and have same build being deployed everywhere.
Scene 2:
You have already generated a build and deployed and found something was incorrect with the constants. Having those configurations externalised gives you a liberty to just override it on environment level and change without rebuilding your application.
To understand more about externalising techniques read: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
Here #value is used for reading the values from properties file (it could be a any environment like dev, qa, prod) but we are writing #value on multiple fields it is not recomonded so thats instead of #value we can use #configurableProperties(prefix="somevalue>) and read the property values suppose `
#configurableProperties(prefix="somevalue")
class Foo{
string name;
string address;
}
application.properties:
somevalue.name="your name"
somevalue.address="your address"
`

Spring Boot 2: Using external Property-Files

I have a executeable jar what I want to configure by properties outside of the jar. What works fine is application.properties, when putting it to config folder close to the jar. But I have a second property-file what seems not to be picked up and I would like to have the best practice for that.
The folder config looks like:
In the config-folder you will find:
Both property-files are also in the src/main/resources folder.
My StartClass looks like:
#SpringBootApplication
#PropertySource("migration-shrink.properties")
public class MigrationShrinkApplication implements CommandLineRunner {}
My bat file looks like:
java -jar migration-shrink-0.0.1-SNAPSHOT.jar -Dspring.config.location=./config/migration-shrink.properties
I wanted to separate Spring-Configuration from Application-Configuration, thats why I have two different property-files.
Thank you!
The #PropertySource annotation is not necessary.
As of Spring Boot 2.0, you can declare additional locations with:
-Dspring.config.additional-location=./config/migration-shrink.properties
Keep in mind that those additional locations are searched before others, so values can be overridden in the other locations.
See the Spring Boot reference documentation.

Automatic restart of jar when property file is changed

I have a requirement where I am deploying a jar with its application.properties file outside of it. Is there any way that when I change an property in application.properties the jar automatically detects the changes and restarts/redeploys itself?
#RefreshScope annotation is provided in spring-boot.
By use of this annotation, you can reload a property value(use inside your code) from .properties.
here is the link for reference :http://projects.spring.io/spring-cloud/spring-cloud.html (Search #RefreshScope).
The idea is to reload whole bean(which is annotated with #RefreshScope),after hitting /refresh end point & you do not need to restart webapp again.
Read about http://cloud.spring.io/spring-cloud-config/
One of options is to restart/reload application after change in properties files.

Resources