【问题标题】:Issue with reading CF environment variables in application.properties file在 application.properties 文件中读取 CF 环境变量时出现问题
【发布时间】:2021-05-31 14:52:29
【问题描述】:

我很难将 spring-webmvc 应用程序部署到 Cloud Foundry。错误与应用程序有关。CF 环境无法解析属性占位符。错误如下

22:14:41.152: [APP/PROC/WEB.0] [CONTAINER] org.apache.jasper.servlet.TldScanner               INFO    At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
22:14:41.215: [APP/PROC/WEB.0] [CONTAINER] lina.core.ContainerBase.[Catalina].[localhost].[/] INFO    No Spring WebApplicationInitializer types detected on classpath
22:14:41.544: [APP/PROC/WEB.0] [CONTAINER] lina.core.ContainerBase.[Catalina].[localhost].[/] INFO    Initializing Spring root WebApplicationContext
22:14:41.947: [APP/PROC/WEB.0] [CONTAINER] org.cloudfoundry.reconfiguration.ProfileUtils      INFO    'cloud' profile activated
22:14:42.088: [APP/PROC/WEB.0] [CONTAINER] n.CloudPropertySourceApplicationContextInitializer INFO    'cloud' property source added
22:14:42.090: [APP/PROC/WEB.0] [CONTAINER] erviceReconfigurationApplicationContextInitializer INFO    Reconfiguration enabled
22:14:42.633: [APP/PROC/WEB.0] 03:14:42.622 [main] ERROR org.springframework.web.context.ContextLoader - Context initialization failed
22:14:42.639: [APP/PROC/WEB.0]  at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:831)
22:14:42.633: [APP/PROC/WEB.0] org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'dataSource' defined in ServletContext resource [/WEB-INF/test-servlet.xml]: Could not resolve placeholder 'datasource.url' in string value "${datasource.url}"; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'datasource.url' in string value "${datasource.url}"
22:14:42.633: [APP/PROC/WEB.0]  at org.springframework.beans.factory.config.PlaceholderConfigurerSupport.doProcessProperties(PlaceholderConfigurerSupport.java:211) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]

我正在使用 concourse 将应用程序部署到 CF。以下是我的管道代码:

jobs:
- name: maven-build-and-deploy
  serial: true
  public: true
  plan: 
  - get: mygit
  - task: mvn-package
    privileged: true
    config:
      platform: linux
      image_resource:
        type: docker-image
        source:
          repository: test/alpine-jdk8-maven
          tag: latest
      inputs:
      - name: test11
      outputs:
      - name: maven-package-output
      run:
        path: sh
        args:
        -  -exc
        -   |
              set -xe
              cd test
              mvn package
              cp target/test.war ../maven-package-output
  - put: cf-push
    resource: cf-env
    params:
      path: maven-package-output/test.war
      manifest: test/manifest.yml
      environment_variables:
        datasource.url: ((datasource.url))
        datasource.username: ((datasource.username))
        datasource.password: ((datasource.password))

以上环境变量是在 Cloud Foundry 中配置的。 这些环境变量由 application.properties 文件读取,这会导致问题。

我已经在本地 tomcat 中配置了相同的应用程序。创建了一个带有属性的 setenv.sh 文件并复制到 tomcat/bin 文件夹。当部署成功时。

部署到 CF 时,会导致问题。

下面是我的 pom.xml,只包括依赖项

 <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${springframework.version}</version>
        </dependency>
<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>${spring.jpa.data.version}</version>
        </dependency>

application.properties

database.url = ${datasource.url}
database.username = ${datasource.username}
database.password = ${datasource.password}

test-servlet.xml(上下文加载器)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:task="http://www.springframework.org/schema/task"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
                  http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
                  http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
                  http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
                  http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd">

    <context:property-placeholder location="classpath:application.properties" />
    

    <tx:annotation-driven transaction-manager="transactionManager"/>

  <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${database.driverClassName}" />
    <property name="url" value="${database.url}" />
    <property name="username" value="${database.username}" />
    <property name="password" value="${database.password}" />
  </bean>

application.properties 如何从 CF 环境中读取环境变量。 请帮助解决此问题。

【问题讨论】:

  • 请告诉我如何处理这个问题?
  • 启用自动重新配置后,我可以获得数据源连接。但我仍然想阅读用户定义的属性。我尝试使用 VCAP 阅读它们。还没读完

标签: java maven spring-mvc cloud-foundry concourse


【解决方案1】:

在您的管道中,您正在设置这些环境变量:

        datasource.url: ((datasource.url))
        datasource.username: ((datasource.username))
        datasource.password: ((datasource.password))

我看到的一个问题,可能还有其他问题,datasource.url 是将使用的实际环境变量名称,但是,从技术上讲,这不是一个有效的环境变量名称。不允许使用 .- 也不是)。这些变量最终不会被设置,因为由于无效字符,shell 会将它们过滤掉。

Allowed characters in Linux environment variable names

Spring Boot 文档中的建议是命名环境变量:

  1. 全部大写
  2. 将空格和.(点或句点)更改为_(下划线)
  3. 删除-

所以如果你想设置datasource.url属性,你需要设置DATASOURCE_URL。同样,如果你想设置属性foo.bar-prop,你需要设置一个环境变量FOO_BARPROP

有关更多信息,请参阅有关宽松绑定的文档:https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config-relaxed-binding

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-25
    • 2017-03-06
    • 2011-01-16
    • 2013-05-27
    • 2012-02-08
    • 2015-06-17
    • 1970-01-01
    • 2020-11-28
    相关资源
    最近更新 更多