Spring Cloud Data Flow 2.9.6部署Java 17应用失败求助
当前使用Spring Cloud Data Flow 2.9.6版本,此前所有应用均基于Java 8部署在Pivotal Cloud Foundry环境中。目前正进行版本迁移,已将部分应用升级至Java 17和21,并通过以下两项配置尝试部署流:
- 在流定义中添加配置:
--JBP_CONFIG_OPEN_JDK_JRE='{jre: { version: 17.+ }}' - 为应用添加部署器属性:
deployer.appname.cloudfoundry.use-spring-application-json: false
部署未成功,Skipper日志中出现如下错误:
Exception in thread "skipperStateMachineTaskExecutor-4" 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 at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:756) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:473) at java.net.URLClassLoader.access$100(URLClassLoader.java:74) at java.net.URLClassLoader$1.run(URLClassLoader.java:369) at java.net.URLClassLoader$1.run(URLClassLoader.java:363) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:362) at java.lang.ClassLoader.loadClass(ClassLoader.java:418) at java.lang.ClassLoader.loadClass(ClassLoader.java:351) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:348) at org.springframework.cloud.deployer.spi.cloudfoundry.CfEnvAwareResource$CfEnvResolver.hasCfEnv(CfEnvAwareResource.java:145) at org.springframework.cloud.deployer.spi.cloudfoundry.CfEnvAwareResource.(CfEnvAwareResource.java:53) at org.springframework.cloud.deployer.spi.cloudfoundry.CfEnvAwareResource.of(CfEnvAwareResource.java:49) at org.springframework.cloud.deployer.spi.cloudfoundry.CfEnvAwareAppDeploymentRequest.(CfEnvAwareAppDeploymentRequest.java:35) at org.springframework.cloud.deployer.spi.cloudfoundry.CfEnvAwareAppDeploymentRequest.of(CfEnvAwareAppDeploymentRequest.java:30) at org.springframework.cloud.deployer.spi.cloudfoundry.CloudFoundryAppDeployer.deploy(CloudFoundryAppDeployer.java:98) at org.springframework.cloud.skipper.server.deployer.DefaultReleaseManager.install(DefaultReleaseManager.java:142) at org.springframework.cloud.skipper.server.service.ReleaseService.install(ReleaseService.java:198) at org.springframework.cloud.skipper.server.service.ReleaseService.install(ReleaseService.java:184) at org.springframework.cloud.skipper.server.service.ReleaseService.install(ReleaseService.java:145) at org.springframework.cloud.skipper.server.service.ReleaseService$$FastClassBySpringCGLIB$$f1c5f0a2.invoke() at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708) at org.springframework.cloud.skipper.server.service.ReleaseService$$EnhancerBySpringCGLIB$$1c3625ff.install() at org.springframework.cloud.skipper.server.statemachine.InstallInstallAction.executeInternal(InstallInstallAction.java:69) at org.springframework.cloud.skipper.server.statemachine.AbstractAction.execute(AbstractAction.java:41) at org.springframework.statemachine.state.AbstractState.executeAction(AbstractState.java:496) at org.springframework.statemachine.state.ObjectState.entry(ObjectState.java:158) at org.springframework.statemachine.support.AbstractStateMachine.entryToState(AbstractStateMachine.java:1322) at org.springframework.statemachine.support.AbstractStateMachine.entryToState(AbstractStateMachine.java:1263) at org.springframework.statemachine.support.AbstractStateMachine.setCurrentStateInternal(AbstractStateMachine.java:1059) at org.springframework.statemachine.support.AbstractStateMachine.setCurrentState(AbstractStateMachine.java:1033) at org.springframework.statemachine.support.AbstractStateMachine.switchToState(AbstractStateMachine.java:926) at org.springframework.statemachine.support.AbstractStateMachine.access$500(AbstractStateMachine.java:82) at org.springframework.statemachine.support.AbstractStateMachine$3.transit(AbstractStateMachine.java:334) at org.springframework.statemachine.support.DefaultStateMachineExecutor.handleInitialTrans(DefaultStateMachineExecutor.java:302) at org.springframework.statemachine.support.DefaultStateMachineExecutor.processTriggerQueue(DefaultStateMachineExecutor.java:398) at org.springframework.statemachine.support.DefaultStateMachineExecutor.access$200(DefaultStateMachineExecutor.java:64) at org.springframework.statemachine.support.DefaultStateMachineExecutor$1.run(DefaultStateMachineExecutor.java:330) at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) at org.springframework.statemachine.support.DefaultStateMachineExecutor.scheduleEventQueueProcessing(DefaultStateMachineExecutor.java:353) at org.springframework.statemachine.support.DefaultStateMachineExecutor.execute(DefaultStateMachineExecutor.java:162) at org.springframework.statemachine.support.DefaultStateMachineExecutor.doStart(DefaultStateMachineExecutor.java:174) at org.springframework.statemachine.support.LifecycleObjectSupport.start(LifecycleObjectSupport.java:120) at org.springframework.statemachine.support.AbstractStateMachine.doStart(AbstractStateMachine.java:418) at org.springframework.statemachine.support.LifecycleObjectSupport.start(LifecycleObjectSupport.java:120) at org.springframework.statemachine.state.StateMachineState.entry(StateMachineState.java:236) at org.springframework.statemachine.support.AbstractStateMachine.entryToState(AbstractStateMachine.java:1322) at org.springframework.statemachine.support.AbstractStateMachine.entryToState(AbstractStateMachine.java:1263) at org.springframework.statemachine.support.AbstractStateMachine.setCurrentStateInternal(AbstractStateMachine.java:1059) at org.springframework.statemachine.support.AbstractStateMachine.setCurrentState(AbstractStateMachine.java:1033) at org.springframework.statemachine.support.AbstractStateMachine.switchToState(AbstractStateMachine.java:926) at org.springframework.statemachine.support.AbstractStateMachine.access$500(AbstractStateMachine.java:82) at org.springframework.statemachine.support.AbstractStateMachine$3.transit(AbstractStateMachine.java:337) at org.springframework.statemachine.support.DefaultStateMachineExecutor.handleTriggerTrans(DefaultStateMachineExecutor.java:287) at org.springframework.statemachine.support.DefaultStateMachineExecutor.handleTriggerTrans(DefaultStateMachineExecutor.java:210) at org.springframework.statemachine.support.DefaultStateMachineExecutor.processTriggerQueue(DefaultStateMachineExecutor.java:450) at org.springframework.statemachine.support.DefaultStateMachineExecutor.access$200(DefaultStateMachineExecutor.java:64) at org.springframework.statemachine.support.DefaultStateMachineExecutor$1.run(DefaultStateMachineExecutor.java:324) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:750)
请问这是Spring Cloud Data Flow/Skipper Server版本限制导致的,还是需要调整其他属性才能解决?
这是Skipper Server运行环境的Java版本与依赖库不兼容导致的问题,和Spring Cloud Data Flow/Skipper的版本本身限制无关,核心原因是:
- Skipper Server自身运行在Java 8环境中,而它尝试加载的
io.pivotal.cfenv.core.CfEnv类是用Java 17(class file version 61.0)编译的,Java 8仅支持最高52.0版本的类文件,因此抛出UnsupportedClassVersionError。
解决步骤
升级Skipper Server的Java版本
将Skipper Server的运行环境切换到Java 17(和目标应用版本一致)。Spring Cloud Data Flow 2.9.6官方支持Java 8/11/17,无需升级SCDF/Skipper版本,只需调整Skipper Server的部署JRE配置即可。这是最彻底、最推荐的解决方式。临时调整依赖版本(不推荐长期使用)
如果暂时无法升级Skipper的Java版本,可以在Skipper的依赖管理中降低cfenv库的版本,确保其编译版本不超过Java 8。但这种方式可能引发其他兼容性问题,仅作为短期过渡方案。验证应用配置的作用范围
确认流定义中的JBP_CONFIG_OPEN_JDK_JRE配置仅作用于目标应用实例,而非Skipper Server本身——该配置是指定应用使用的JRE版本,Skipper Server的JRE版本需要单独配置。
内容的提问来源于stack exchange,提问作者CuriousK

