I am trying to update our instance of Spring Cloud DataFlow from 2.9.4 to 2.11.2 but I'm getting errors during deployment to our PCF (Pivotal CloudFoundry) environment. I am totally unsure about what to do so I was hoping someone here would have an idea.
I am deploying through a custom manifest as we have custom configuration requirements that as far as we are able to tell cannot be covered by using the SCDF from the PCF marketplace. Specifically this comes down to disabling streams, but in full the custom manifest is:
applications:
- name: scdf-server
buildpacks:
- java_buildpack_latest
path: spring-cloud-dataflow-server-2.11.2.jar
routes:
- route: https://our-scdf-route.some-pcf-host.com
health-check-type: http
health-check-http-endpoint: /management/health
memory: 2G
disk_quota: 2G
instances: 1
timeout: 180
services:
- postgres-database
- config-service
env:
LANG: en_US.utf8
LC_ALL: en_US.utf8
SPRING_APPLICATION_NAME: scdf-server
SPRING_PROFILES_ACTIVE: cloud
JBP_CONFIG_OPEN_JDK_JRE: '{ jre: { version: 17.+ } }'
JAVA_OPTS: '-Duser.timezone=Europe/Amsterdam'
JBP_CONFIG_SPRING_AUTO_RECONFIGURATION: '{enabled: false}'
SPRING_CLOUD_DATAFLOW_FEATURES_STREAMS_ENABLED: false
SPRING_CLOUD_SKIPPER_SERVER_ENABLE_LOCAL_PLATFORM: false
SPRING_CLOUD_KUBERNETES_DISCOVERY_ENABLED: false
KUBERNETES_AUTH_TRYKUBECONFIG: false
SPRING_AUTOCONFIGURE_EXCLUDE: org.springframework.cloud.deployer.spi.kubernetes.KubernetesAutoConfiguration
SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE: 6
SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE: 1
# Release connection after 10 seconds idle.
SPRING_DATASOURCE_HIKARI_IDLE_TIMEOUT: 10000
SPRING_CLOUD_SKIPPER_CLIENT_SERVER_URI: https://our-scdf-skipper-server-route.some-pcf-host.com/api
SPRING_CLOUD_DATAFLOW_SERVER_URI: https://our-scdf-route.some-pcf-host.com
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_URL: ((CF_API_URL))
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_DOMAIN: ((APP_DOMAIN))
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_ORG: ((CF_ORG))
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_SPACE: ((CF_SPACE))
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_USERNAME: ((CF_USER))
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_PASSWORD: ((CF_PASSWORD))
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_SKIP_SSL_VALIDATION: true
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_SCHEDULERURL: ((SCHEDULER_URL))
# Set buildpacks to empty so that CloudFoundry let the buildpacks decide whether they can run the app
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_BUILDPACKS: ""
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_BUILDPACK: ""
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_SERVICES: postgres-database, config-service # other services...
# Composed task runner requires at least 4 connections.
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_ENV[SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE]: 4
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_ENV[SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE]: 0
# Release connection after 10 seconds idle.
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_ENV[SPRING_DATASOURCE_HIKARI_IDLE_TIMEOUT]: 10000
# Let the nodejs buildpack set the max_old_space_size for nodejs apps
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_ENV[OPTIMIZE_MEMORY]: true
# Let the application know which space we are running on:
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_ENV[CF_SPACE]: ((CF_SPACE))
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_HEALTHCHECK: process
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_USESPRINGAPPLICATIONJSON: false
SPRING_CLOUD_DEPLOYER_CLOUDFOUNDRY_ENABLE_RANDOM_APP_NAME_PREFIX: true
SPRING_CLOUD_DATAFLOW_FEATURES_SCHEDULES_ENABLED: true
# Suppress warning exception for k8s config
LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_CLOUD_KUBERNETES_FABRIC8_CONFIG: INFO
SPRING_APPLICATION_JSON: '
{
"maven" : {
"localRepository": null,
"remoteRepositories" : {
"springRepo" : {
"url" : "((NEXUS_URL))((NEXUS_INTERNAL_REPO))",
"auth": {
"username": "((NEXUS_USER))",
"password": "((NEXUS_PASSWORD))"
}
},
"repo2": {
"url": "((NEXUS_URL))((NEXUS_EXTERNAL_REPO))"
}
}
},
"spring.cloud.dataflow" : {
"task.platform.cloudfoundry.accounts" : {
"default" : {
"connection" : {
"url" : "((CF_API_URL))",
"domain" : "((APP_DOMAIN))",
"org" : "((CF_ORG))",
"space" : "((CF_SPACE))",
"username" : "((CF_USER))",
"password" : "((CF_PASSWORD))",
"skipSsValidation" : true
},
"deployment" : {
"services" : "postgres-database, config-service"
}
}
}
}
}'
This largely follows the documentation: https://dataflow.spring.io/docs/installation/cloudfoundry/cf-cli/#installing-using-a-manifest
The URL of the JAR we download for deployment is https://repo.maven.apache.org/maven2/org/springframework/cloud/spring-cloud-dataflow-server/2.11.2/spring-cloud-dataflow-server-2.11.2.jar
When deploying this manifest with the command:
cf push ${APP_NAME_NEW} \
-f ${MANIFEST_FILE} \
-p "${ARTIFACT_FILE}" \
--no-start \
--var COMMITREF="${COMMITREF}" \
--var CF_SPACE="${CF_SPACE}" \
--var CF_ORG="${cfOrg}" \
--var CF_API_URL="${cfApi}" \
--var APP_DOMAIN="${APP_DOMAIN}" \
--var CF_USER="${cfUser}" \
--var CF_PASSWORD="${cfPass}" \
--var NEXUS_USER="${NEXUS_USER}" \
--var NEXUS_PASSWORD="${NEXUS_PASSWORD}" \
--var NEXUS_URL="${NEXUS_URL}" \
--var NEXUS_INTERNAL_REPO="${NEXUS_INTERNAL_REPO}" \
--var NEXUS_EXTERNAL_REPO="${NEXUS_EXTERNAL_REPO}" \
--var SCHEDULER_URL="${SCHEDULER_URL}"
Between push and start our script only uses cf set-env
to set the HTTP proxy.
Now as for the error I get, this is the logging of when starting the application on our PCF. I have dumped this on gist because otherwise this post exceeds the maximum body length: https://gist.github.com/favna/05f42f8ab1e55f3548f599fa2d0df558
As can be seen here I get some error about an unresolved namespace seemingly related to K8s, despite the fact that above the Spring banner it explicitly logs that it detects not running in K8s and disabling its profile activation.
So far I have tried:
"spring.cloud.dataflow"
section at the bottom, however this didn't change the error (although I suspect it was a necessary change regardless?)I would expect deployment of the new SCDF version to work smoothly so we can start testing it and eventually using it.
The primary reason for wanting to update is that when updating our applications to Spring Boot 3.2.0 (from 3.1.5) as well as updating the matching org.springframework.cloud:spring-cloud-dependencies
from 2022.0.4
to 2023.0.0
that currently I get the error in SCDF 2.9.4:
Handler dispatch failed; nested exception is java.lang.UnsupportedClassVersionError: io/pivotal/cfenv/core/CfEnv has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 52.0
Seeing as this is clearly related to Java vesions I figured I'd upgrade SCDF and add the config lines for using Java 17 (JBP_CONFIG_OPEN_JDK_JRE: '{ jre: { version: 17.+ } }'
and BP_JVM_VERSION: -jdk17
) and then go from there.
I figured it out. In the end, I found this GitHub issue and added SPRING_CLOUD_KUBERNETES_ENABLED: false
to my env
section of the manifest.yml
and now the application starts successfully.