Приложение Spring Boot не может считывать свойства среды

#linux #spring #spring-boot #tomcat #environment-variables

#linux #spring #spring-boot #tomcat #переменные среды

Вопрос:

У меня есть приложение Spring Boot, в котором я использую свойства среды для yml файла.

Мой application.yml выглядит так:

 spring:
  datasource:
    url: ${DB_URL}
    driver-class-name: ${DB_DRIVER}
    username: ${DB_USERNAME}
    password: ${DB_PASSWORD}
    connectionTestQuery: SELECT 1 FROM DUAL
    max-wait: ${database.max-wait:5000}
    max-active: ${database.max-active:500}
    test-on-borrow: ${database.test-on-borrow:true}
    initialization-mode: always
  

Когда я попытался развернуть его на внешнем хосте через Tomcat, приложение не может запуститься, потому что оно не может прочитать переменные среды.
Я получаю следующую ошибку

 Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker': Invocation of init method failed; nested exception is org.springframework.jdbc.datasource.init.UncategorizedScriptException: Failed to execute database script; nested exception is org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLException: Access denied for user '${DB_USERNAME}'@'localhost' (using password: YES)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1794)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516)
            at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324)
            at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
            at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
            at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:227)
            at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1175)
            at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveBean(DefaultListableBeanFactory.java:420)
            at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:350)
            at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:343)
            at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerPostProcessor.postProcessAfterInitialization(DataSourceInitializerPostProcessor.java:52)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:430)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1798)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
            ... 134 more
  

Я использую сервер Ubuntu. Я установил переменные среды на /etc/environment , и они выглядят следующим образом

 DB_URL="jdbc:mysql://XX.XX.XX.XX:3306/XXXXX"
DB_USER="XXXXX"
DB_PASSWORD="XXXXX"
DB_DRIVER="com.mysql.cj.jdbc.Driver"
  

Когда я запускаю команду set , они отлично отображаются там.
Я также попытался создать setenv.sh файл под /opt/tomcat/bin , который выглядит следующим образом:

 #!/bin/bash
export DB_DRIVER=com.mysql.cj.jdbc.Driver
export DB_PASSWORD=XXXXXX
export DB_URL=jdbc:mysql://XX.XX.XX.XX:3306/XXXXX
export DB_USER=XXXXXX
  

Я не пытался сделать это в профиле, потому что, согласно этой теме, этого должно быть достаточно с /etc/environment :
https://unix.stackexchange.com/questions/117467/how-to-permanently-set-environmental-variables

Есть идеи, чего мне может не хватать?

Комментарии:

1. Вы убедились, что ваш setenv.sh доступен tomcat? Также установлены CATALINA_BASE и CATALINA_HOME ? Ссылка: здесь

2. @Sajjad я добавил CATALINA_HOME в /etc/environments и setenv.sh имеет разрешения на чтение и выполнение. Есть ли что-нибудь еще, что нужно сделать?

Ответ №1:

Возможно, вы вводите неправильные учетные данные. Просто перепроверьте те же учетные данные с помощью некоторых инструментов MySQL GUI, таких как workbench, sqlyog….

Комментарии:

1. Да, я это сделал, и, как вы можете видеть в исключении, он использует обычный текст переменных среды в yml.

Ответ №2:

Вы можете использовать spring.config.location для настройки явного пути к вашим внешним файлам конфигурации. Затем вы можете настроить свое приложение Spring Boot так, чтобы оно загружало их как системные свойства при запуске.

Например

 Properties props = new Properties();
props.setProperty("spring.config.location",<your config file path>);
  

Источник: здесь

Комментарии:

1. Но моя проблема не в том, где находится файл конфигурации, и я бы предпочел избежать его экстернализации. Я хочу, чтобы Spring boot мог считывать переменные среды.

Ответ №3:

В вашем файле свойств Spring boot, который вы используете

${DB_USERNAME}

и в файле конфигурации bash, который вы используете

экспорт DB_USER=XXXXXX

измените файл bash на

экспортировать ${DB_USERNAME}=XXXXXX