【问题标题】:Spring Boot app is not able to read environment propertiesSpring Boot 应用程序无法读取环境属性
【发布时间】:2020-08-30 10:56:15
【问题描述】:

我有一个 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 时,它们完美地显示在那里。 我还尝试在/opt/tomcat/bin 下创建一个setenv.sh 文件,如下所示:

#!/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

知道我可能缺少什么吗?

【问题讨论】:

  • 您确定您的setenv.sh 可以被tomcat 访问吗?还设置了CATALINA_BASE 和CATALINA_HOME?参考:here
  • @Sajjad 我在/etc/environments 中添加了CATALINA_HOME 和setenv.sh 具有读取和执行权限。还有什么可以做的吗?

标签: linux spring spring-boot tomcat environment-variables


【解决方案1】:

可能是您输入了错误的凭据。只需使用一些 MySql GUI 工具(如工作台、sqlyog....)交叉检查相同的凭据即可。

【讨论】:

  • 是的,我做到了,正如您在异常中看到的那样,它使用了 yml 中环境变量的纯文本。
【解决方案2】:

您可以使用spring.config.location 为您的外部化配置文件设置显式路径。然后,您可以配置您的 Spring Boot 应用程序以在启动时将它们作为系统属性加载。

例如

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

来源:here

【讨论】:

  • 但我的问题不在于配置文件所在的位置,我更愿意避免将其外部化。我希望能够让 spring boot 读取环境变量。
【解决方案3】:

在您正在使用的 Spring Boot 属性文件中

${DB_USERNAME}

在你正在使用的 bash 配置文件中

导出 DB_USER=XXXXXX

将 bash 文件更改为

导出 ${DB_USERNAME}=XXXXXX

【讨论】:

    猜你喜欢
    • 2021-03-12
    • 2019-09-18
    • 2017-06-26
    • 1970-01-01
    • 2021-09-01
    • 2014-01-07
    • 2017-07-03
    • 2019-12-12
    • 1970-01-01
    相关资源
    最近更新 更多