24

I have a spring boot application which interacts with DB to provide resource using Spring data Rest. I want to get the configuration from environment variables. Below is my properties file.

spring.datasource.url=${mysql.url}
spring.datasource.username=${mysql.user}
spring.datasource.password=${mysql.password}

And my environment variables are in the image https://ibb.co/cyxsNc

I even tried with the below config too

spring.datasource.url=${MySQL_Url}
spring.datasource.username=${MySQL_User}
spring.datasource.password=${MySQL_Password}

But I am not able to connect to the DB and getting the below error

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Tomcat.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.tomcat.jdbc.pool.DataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.IllegalArgumentException: URL must start with 'jdbc'

Application folder structure

Project
|-- src/main/java
    |-- com.example.app
        |-- DemoApplication.java
|-- src/main/resources
    |-- application.properties

Note: The configuration works fine if I set the values like below

spring.datasource.url=jdbc:mysql://localhost:3306/ex_man
spring.datasource.username=root
spring.datasource.password=root

What am I missing?

5
  • 1
    Don't use a screenshot, as the host could go down. A code excerpt is preferable. Commented Feb 20, 2018 at 19:46
  • @Sp Sesha, please post your main configuration class (if any) and project structure. Most likely your application context is not picking up your application.properties file (should be on your classpath). Commented Feb 20, 2018 at 20:05
  • Well then your environment variables are not loaded with your application. How do you load them into the project? Commented Feb 20, 2018 at 21:14
  • where you able to solve your problem? Commented Apr 26, 2018 at 13:00
  • Possible duplicate of Using env variable in Spring Boot's application.properties Commented Oct 11, 2018 at 2:45

2 Answers 2

18

Check out this documentation here: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

try naming your environment variables:

SPRING_DATASOURCE_URL

SPRING_DATASOURCE_USERNAME

SPRING_DATASOURCE_PASSWORD

UPDATE:

Spring boot does properly pick up the environment variables, see test below.

package com.example.environment_vars;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import java.util.Map;      // Import this for systemEnvironment

@SpringBootApplication
public class EnvironmentVarsApplication {

    @Value("#{systemEnvironment['ENV_VAR'] ?: 'Default_value'}")
    private String envVar;
    
    @Bean
    public CommandLineRunner commandLineRunner() {
        return new CommandLineRunner() {
            @Override
            public void run(String[] arg0) throws Exception {
                System.out.println(envVar);
            }
        };
    }
    
    public static void main(String[] args) {
        SpringApplication.run(EnvironmentVarsApplication.class, args);
    }
}

This will print out the value of the environment variable ENV_VAR and if the value is not present, it will print the Default_Value.

@Value injects the value accessible throughout the project.

Sign up to request clarification or add additional context in comments.

11 Comments

Do I need to have a default value specified in the properties file or the environmental variables is enough?
According to the docs the environment variable should be enough, I haven't tested this out though. Give it a quick test and if it doesn't work we can try another method.
If I try without a default value in properties file, I am getting an error saying the application failed to start and the description is Cannot determine embedded database driver class for database type NONE
Did you make sure to export the environment variables? In the update above I tested and confirmed that the environment variables are picked up by spring boot. Are you running in tomcat or another web server? That may affect access to the environment variables.
@AleksandrErokhin You can find the conversion documentation here: docs.spring.io/spring-boot/docs/current/reference/html/…
|
7

You can use a DataSource configuration file and obtain environment variables using System.getEnv("ENV_VARIABLE") method.

First you should remove properties starting with "spring.datasource." in application.properties. Then include this ready to go configuration file:

import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
class JpaConfig {

    @Bean
    public DataSource getDataSource() {
        return DataSourceBuilder.create()
                .driverClassName("com.mysql.cj.jdbc.Driver")
                .url(getDataSourceUrl())
                .username(System.getenv("DB_USERNAME"))
                .password(System.getenv("DB_PASSWORD"))
                .build();
    }

    private String getDataSourceUrl() {
        return "jdbc:mysql://"
                + System.getenv("DB_HOST") + "/"
                + System.getenv("DB_NAME")
                + "?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false";
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.