Spring #Value returns <empty> - spring

I have checked similiar questions:
Spring - #Value returns null
Spring Boot: #Value returns always null
Yet, I cannot find what is wrong with my annotation
This how the code looks in IntelliJ
screenshot from IntelliJ
This is whats beneath
#Component
public class VisitMapper {
#Value("${spring.datasource.url}")
private String url;
#Value("${spring.datasource.username}")
private String username;
#Value("${spring.datasource.password}")
private String password;
//more code below
I have two .properties files: application-dev.properties and application.properties.
Active profile is set to dev.
In application-dev.properties I have:
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=postgres
Not sure if it is important since active profile is set to dev, but in application.properties I have:
spring.datasource.url=
spring.datasource.username=
spring.datasource.password=
To sum up - why is password value shown as empty?

I suspect that either Intellij hides the fields with password in them (although <empty> is a bit of a crappy filler) or Intellij has a hard time resolving the right property value for that field (for whatever reason).
However the fact that your application starts indicates that, at least, Spring Boot does resolve the properties correctly, else it wouldn't start and blow up. It wouldn't start either due to not being able to resolve the property or due to not being able to connect to the database.

Related

Get Application Name Spring boot

I'm building a module to save the data into the database. After finishing the module I will make it into a JAR which is common and anyone will call static method. There is a parameter its name application name i don’t want pass this value I want get this value dynamic after add jar to any spring boot application , then any one call this static method retrieve name application dynamic , so the spring boot contains the application properties have value spring.application.name I want get this value inside my module it’s doable ? it’s possible to get this value
I searched and found this implementation:
#Value("${spring.application.name}")
private String appName;
My class:
public class BackEnd {
#Value("${spring.application.name}")
static String applicationName;
private static void saveData(String messsage) {
DAO dao= new DAO()
dao.saveData(messsage,applicationName);
}
}
So currently the applicationName value is null. Is it the correct implementation?
The property name is correct and used by a handful of Spring Boot projects. You need to define this property yourself as Spring Boot default is an empty value as per docs:
# IDENTITY (ContextIdApplicationContextInitializer)
spring.application.name= # Application name.
You can use the usual application.yml file e.g.
spring:
application:
name: MyApp
well, the property name is correct but you need to define that property in application.properties or application.yml file as follows.
if you are using application.properties file define property as follows
spring.application.name= # your application name
if you are using application.yml file define property as follows
spring:
application:
name: # your application name

Spring Boot Properties as Environment variables

I have come across some behaviour which seems inconsistent in how spring boot handles environment variables in application properties files vs configuration property classes. I am unsure whether this is a bug in spring or an error in my understanding of what "ought" to happen.
I have
#Data
#ConfigurationProperties("foo")
#Validated
public class ClientProperties {
#NotBlank
private String apiKey;
#NotBlank
private String uri;
}
In the application.properties file I have:
foo.baseUri=https://system.appspot.com
foo.uri=${foo.baseUri}/Valuation?apikey=${foo.apiKey}&bar={bar}
Setting Just FOO_APIKEY
If I run my app with:
export FOO_APIKEY=DEF
Then I get
APPLICATION FAILED TO START
***************************
Description:
Binding to target class ClientProperties(apiKey=null, uri=https://system.appspot.com/Valuation?apikey=DEF&bar={bar}) failed:
Property: foo.apiKey
Value: null
Reason: may not be empty
Note that in the URI the api key is set as expected as well as the base URI
Setting Just FOO_API_KEY
Next, if instead, I try to set just this property (remove the old env var):
export FOO_API_KEY=ABC
Then my app starts, but the values are not as expected. My logs show:
API Key: ABC.
URI Property: ${foo.baseUri}/Insurance?apikey=${foo.apiKey}&bar={bar}.
Note that now the base uri also disappeared as well as the API key being missing.
Setting Both Properties FOO_API_KEY and FOO_APIKEY
When I set both environment variables the app starts but the apiKey property of ClientProperties holds the value of the FOO_APIKEY export, where as the uri property of ClientProperties holds the value of the FOO_API_KEY export.
API KEY IS: ABC.
URI IS: https://system.appspot.com/Insurance?apikey=DEF&bar={bar}.
Notes
I actually don't need the value from ClientProperties.apiKey. It's only ever used in the app via the ClientProperties.uri which is already being resolved in application.properties. However, I specify the property so that I can have validation to ensure the value gets set. I could remove the value from my class and everything would be ok - expect then I lose my validation.
Spring boot version is: 1.5.10.RELEASE

springboot + JDBTemplate (No datasource specified error even though specified in application.properties

Application.properties
spring.datasource.url=
spring.datasource.username=
spring.datasource.password=
spring.datasource.driver-class-name=
i placed this application.properties in resources folder.
Java Class
#Component
public class data{
#Autowired
private JdbcTemplate jdbcTemplate;
public void queryData(){
String sql = "select * from DEPOSIT";
jdbcTemplate = new JdbcTemplate();
jdbcTemplate.execute(sql);
}
}
I am getting
java.lang.Illegal Argument Exception:No Data Source Specified
I am getting this error message even though i specified data source in application.properties
I am using Spring Boot for this task. I Have added almost all the dependencies required in POM.
Not sure why i am not able to access data source. basically trying to access data from DB using Spring boot, MySQL, jdbcTemplate.
Not sure whats wrong here.
Do i have to add anything in the code so that data source can be specified in java class?
Add below properties to your application.properties file. This specifies the data source for your application. Do check if mysql is running on your machine before starting your application.
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost:3306/db
spring.datasource.username=yourusername
spring.datasource.password=yourpassword
For additional information refer to below link:
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html

Spring Properties showing as Null

I have a Spring Boot application, generated by JHipster.
Am trying to add some new properties to the application-dev.yml file but my class is seeing the values null, even after spending some hours with Google.
Added the following to the top of application-dev.yml:
host: 1.2.3.4
port: 5555
In my class I have
#Component
public class ExampleUtils {
#Value("${host}")
private String host;
#Value("${port}")
private String port;
}
The class is in a new directory under the source root.
Thanks in advance.
in your application.properties set
spring.profiles.active=dev
or when you run the application parse the command line args follows
-Dspring.profiles.active=dev
It is a good practice to add the new properties you add to a #ConfigurationProperties class.
At least this way I never had problems adding properties.
Have a look at the docs : http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties

Reload property value when external property file changes ,spring boot

I am using spring boot, and I have two external properties files, so that I can easily change its value.
But I hope spring app will reload the changed value when it is updated, just like reading from files. Since property file is easy enough to meet my need, I hope I don' nessarily need a db or file.
I use two different ways to load property value, code sample will like:
#RestController
public class Prop1Controller{
#Value("${prop1}")
private String prop1;
#RequestMapping(value="/prop1",method = RequestMethod.GET)
public String getProp() {
return prop1;
}
}
#RestController
public class Prop2Controller{
#Autowired
private Environment env;
#RequestMapping(value="/prop2/{sysId}",method = RequestMethod.GET)
public String prop2(#PathVariable String sysId) {
return env.getProperty("prop2."+sysId);
}
}
I will boot my application with
-Dspring.config.location=conf/my.properties
I'm afraid you will need to restart Spring context.
I think the only way to achieve your need is to enable spring-cloud. There is a refresh endpoint /refresh which refreshes the context and beans.
I'm not quite sure if you need a spring-cloud-config-server (its a microservice and very easy to build) where your config is stored(Git or svn). Or if its also useable just by the application.properties file in the application.
Here you can find the doc to the refresh scope and spring cloud.
You should be able to use Spring Cloud for that
Add this as a dependency
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter', version: '1.1.2.RELEASE'
And then use #RefreshScope annotation
A Spring #Bean that is marked as #RefreshScope will get special treatment when there is a configuration change. This addresses the problem of stateful beans that only get their configuration injected when they are initialized. For instance if a DataSource has open connections when the database URL is changed via the Environment, we probably want the holders of those connections to be able to complete what they are doing. Then the next time someone borrows a connection from the pool he gets one with the new URL.
Also relevant if you have Spring Actuator
For a Spring Boot Actuator application there are some additional management endpoints:
POST to
/env to update the Environment and rebind #ConfigurationProperties and log levels
/refresh for re-loading the boot strap context and refreshing the #RefreshScope beans
Spring Cloud Doc
(1) Spring Cloud's RestartEndPoint
You may use the RestartEndPoint: Programatically restart Spring Boot application / Refresh Spring Context
RestartEndPoint is an Actuator EndPoint, bundled with spring-cloud-context.
However, RestartEndPoint will not monitor for file changes, you'll have to handle that yourself.
(2) devtools
I don't know if this is for a production application or not. You may hack devtools a little to do what you want.
Take a look at this other answer I wrote for another question: Force enable spring-boot DevTools when running Jar
Devtools monitors for file changes:
Applications that use spring-boot-devtools will automatically restart
whenever files on the classpath change.
Technically, devtools is built to only work within an IDE. With the hack, it also works when launched from a jar. However, I may not do that for a real production application, you decide if it fits your needs.
I know this is a old thread, but it will help someone in future.
You can use a scheduler to periodically refresh properties.
//MyApplication.java
#EnableScheduling
//application.properties
management.endpoint.refresh.enabled = true
//ContextRefreshConfig.java
#Autowired
private RefreshEndpoint refreshEndpoint;
#Scheduled(fixedDelay = 60000, initialDelay = 10000)
public Collection<String> refreshContext() {
final Collection<String> properties = refreshEndpoint.refresh();
LOGGER.log(Level.INFO, "Refreshed Properties {0}", properties);
return properties;
}
//add spring-cloud-starter to the pom file.
Attribues annotated with #Value is refreshed if the bean is annotated with #RefreshScope.
Configurations annotated with #ConfigurationProperties is refreshed without #RefreshScope.
Hope this will help.
You can follow the ContextRefresher.refresh() code implements.
public synchronized Set<String> refresh() {
Map<String, Object> before = extract(
this.context.getEnvironment().getPropertySources());
addConfigFilesToEnvironment();
Set<String> keys = changes(before,
extract(this.context.getEnvironment().getPropertySources())).keySet();
this.context.publishEvent(new EnvironmentChangeEvent(context, keys));
this.scope.refreshAll();
return keys;
}

Resources