I need to externalize the parameters set in my application.properties using environmental variables.
This is my application.properties file:
spring.datasource.url= jdbc:mysql://${MYSQL_URL}:${MYSQL_PORT}/${MYSQL_DBNAME}
spring.datasource.username= ${MYSQL_USERNAME}
spring.datasource.password= ${MYSQL_PASSWORD}
spring.datasource.driver-class-name= com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto= update
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5Dialect
And those ${---} are Environmental Variables.
But when I try to run my application I get this error:
Property: spring.datasource.url
Value: jdbc:mysql://${MYSQL_URL}:${MYSQL_PORT}/${MYSQL_DBNAME}
Origin: class path resource [application.properties]:1:24
Reason: Could not resolve placeholder 'MYSQL_URL' in value "jdbc:mysql://${MYSQL_URL}:${MYSQL_PORT}/${MYSQL_DBNAME}"
I found that the environment variables were defined after I launched Eclipse, and Eclipse did not recognize them, so the solution was simple: restarting Eclipse.
Related
I have created .env file where I keep variables now I want them to be defined in my application.properties but this is not working. What do I need to add to get the variables.
.env file
MYSQLDB_USER=root
MYSQLDB_ROOT_PASSWORD=root
application.properties
spring.profiles.active = dev
application-dev.properties
# mysql database properties
spring.datasource.url = jdbc:mysql://localhost:3306/testdb?useUnicode=true&serverTimezone=UTC&server&createDatabaseIfNotExist=true
spring.datasource.username = ${MYSQLDB_USER}
spring.datasource.password = ${MYSQLDB_ROOT_PASSWORD}
# hibernate properties
spring.jpa.hibernate.ddl-auto = create
spring.jpa.show-sql = true
This won't happen automatically. You can make it work by adding this to your application-dev.properties:
spring.config.import=optional:file:.env[.properties]
Another option is to use an additional library that adds support for this, such as https://github.com/paulschwarz/spring-dotenv.
There is some discussion about adding support for this in Spring Boot, but it is not a high priority.
I have a Spring boot application with different environments. I have a main application.yml with a set of properties and an application-test.yml for my test environment.
Inside my application.yml, I have the following config
spring:
liquibase:
enabled: false
user: ${SPRING_DATASOURCE_USERNAME}
password: ${SPRING_DATASOURCE_PASSWORD}
change-log: classpath:db/changelog-master.yaml
And inside my application-test.yml, I have the following
spring
liquibase:
user: sa
password: password
I was expecting my test environment to use liquibase.user and liquibase.password from the application-test.yml and pick the two other sub-properties (liquibase.enabled and liquibase.change-log) from application.yml. My reasoning was that in my test environment, the Application context would pick up all the properties in application.yml and then overwrite only the subkeys defined in application-test.yml, while keeping the original values of application.yml if not explicitly overwritten.
But that does not seem to be the case; it looks as if the key liquibase in my application-test.yml overwrites all the key and subkeys of the liquibase defined in application.yml.
Therefore since in my application-test.yml, liquibase.enabled and liquibase.change-log are not defined; the test environment does not know about these values. I was expecting them to be picked up from the main application.yml instead. I tried to define them manually in my application-test.yml and my tests work fine. If I remove them, my tests fail because they use the default properties for liquibase instead of liquibase.enabled: false and liquibase.change-log: classpath:db/changelog-master.yaml
What I would like to do is the following:
In my main application.yml, have
main_key:
sub_key_1: value_1
sub_key_2: value_2
sub_key_3: value_3
And in my application-test.yml, have only
main_key:
sub_key_1: test_value_1
have my test environment pickup sub_key_2: value_2 and sub_key_3: value_3 directly from application.yml, without them being overwritten by nothing in my test environment (since they are not defined in my application-test.yml)
Is it possible to have think kind of logic : if main_key.sub_key_2 is defined in application-test.yml is defined, then use it, otherwise use the main_key.sub_key_2 defined in application.yml ?
I feel that if I don't define all the sub_keys of my main_key in my application-test.yml, it is not possible to do it.
Many thanks for your help
Actually, I think I know why it does not work.
I had an empty application.yml inside my test/resources/application.yml. So I believe spring boot picks up the test/resources/application.yml instead of the src/main/resources/application.yml when test/resources/application.yml exists.
Which explains why the properties in my src/main/resources/application.yml were not picked up at all.
The solution was simply to delete the test/resources/application.yml
I am using to configure spring boot with an external YAML configuration and CMD.
-> application.yml file
spring:
profiles: integration-test
datasource:
driverClassName: ${SPRING_DATASOURCE_DRIVER_CLASS_NAME}
url: ${SPRING_DATASOURCE_URL}
username: ${SPRING_DATASOURCE_USERNAME}
password: ${SPRING_DATASOURCE_PASSWORD}
-> cmd
mvn clean install
-> Result
Caused by: java.lang.IllegalStateException: Cannot load driver class: ${SPRING_DATASOURCE_DRIVER_CLASS_NAME}
Can anyone explain this to me?
When you use the syntax ${}, you are actually telling Spring Boot to use the value of the property whose name is between brackets. In your case, Spring Boot tries to resolve the property SPRING_DATASOURCE_DRIVER_CLASS_NAME. When it fails, it uses the string as is, which leads to the error you mentioned, since no driver exists under the name ${SPRING_DATASOURCE_DRIVER_CLASS_NAME}.
To solve the issue, you can either :
replace the ${} by the real values, e.g. driverClassName: org.postgresql.Driver and do the same for the other properties (url, username and password)
provide properties SPRING_DATASOURCE_DRIVER_CLASS_NAME,SPRING_DATASOURCE_URL and the two others. These can passed in the command line with -D options (e.g. -DSPRING_DATASOURCE_DRIVER_CLASS_NAME=org.postgresql.Driver) or through environment variables. You can look at spring Boot documentation for more details.
Pass those variables in your launch configuration of your program or at commandline when you run your app with java YourMainClass, e.g.
java -DSPRING_DATASOURCE_DRIVER_CLASS_NAME=<full_qualified_name_of_your_jdbc_driver_class> -DSPRING_DATASOURCE_URL=<jdbc_url> YourMainClass
also pass the other two variables the same way, username & password!
your can even set those enviroment variables on OS level, so you don't have to set them each time you start your application...
if your using Spring Boot also have a look at this one: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
I am using spring boot config. My configurations are located in one folder in git.
The folder structure is as follows
application.yml
registry.yml
I have the following property defined in application.yml
registry:
server:
port:${REGISTRY_PORT:8761}
host:${REGISTRY_HOST:localhost}
and than i have the following property defined in registry.yml
server:
port: ${registry.server.port}
I get the following exception during spring boot start up. I feel registy.yml file is loaded first. Any way i can make application.yml file loaded first.
java.lang.IllegalArgumentException: Could not resolve placeholder 'registry.server.port' in value "${registry.server.port}"
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:172) ~[spring-core-5.1.0.RELEASE.jar:5.1.0.RELEASE]
at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:124) ~[spring-core-5.1.0.RELEASE.jar:5.1.0.RELEASE]
at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:237) ~[spring-core-5.1.0.RELEASE.jar:5.1.0.RELEASE]
at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:211) ~[spring-core-5.1.0.RELEASE.jar:5.1.0.RELEASE]
I'm trying to create a Spring Boot application using sqljdbc4 driver with this config:
spring:
datasource:
url: "jdbc:sqlserver://dbhost:1433;databaseName=test"
username: dbuser
password: dbuser
tomcat:
test-on-borrow: true
validation-query: select 1
But, when I run, I get this error: Unable to detect database type
I was debugging BatchDatabaseInitializer, where error came from, and when it calls JdbcUtils.commonDatabaseName(...), "Microsoft SQL Server" is returned as product name that doesn't match with any DatabaseDriver's product name.
I tried other drivers but they all have the same problem.
Is it a bug?
I'm using Spring Boot 1.5.1-RELEASE.
You need to properly configure your spring.datasource config in application.properties file if you're using spring-batch to create batch jobs. Below is mine ->
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/batch_repo
spring.datasource.username=batch_username
spring.datasource.password=batch_password
spring.datasource.platform=mysql
spring.batch.initialize-schema=always
spring.batch.initialize-schema when configured to "always", will create the necessary spring batch related tables in your schema.
Alternatively, if you assign it to "never", it will refrain from creating the tables. In both these cases your error should get resolved.
Try spring.batch.jdbc.initialize-schema=never in props file. It worked for me in spring-boot v2.6.x
Add this in your Application file within the main function.
#SpringBootApplication(
exclude = {
BatchAutoConfiguration.class,
JmxAutoConfiguration.class
},
excludeName = {
"org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration",
}
)
Put this in your application.properties.
spring.batch.schema=classpath:org/springframework/batch/core/schema-sqlserver.sql
Check your application.properties file like below.
Note: springbatch is my DB name
spring.datasource.url=jdbc:mysql://localhost:3306/springbatch
spring.datasource.username=root
spring.datasource.password=Vishal#123
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.batch.jdbc.initialize-schema=always