From 442810565b8dd1f6529b6df6c8eace29117ea64c Mon Sep 17 00:00:00 2001 From: David Byron <82477955+dbyron-sf@users.noreply.github.com> Date: Thu, 27 Oct 2022 09:45:08 -0400 Subject: [PATCH] fix(web): adjust configuration so that the halyard daemon starts with spring boot 2.4 (#1987) Before this, halyard fails to start: $ ./gradlew halyard-web:run > Task :halyard-web:run _ _ _ | |__ __ _| |_ _ __ _ _ __ __| | | '_ \ / _` | | | | |/ _` | '__/ _` | | | | | (_| | | |_| | (_| | | | (_| | |_| |_|\__,_|_|\__, |\__,_|_| \__,_| |___/ 2022-10-26 14:17:00.753 INFO 75718 --- [ main] com.netflix.spinnaker.halyard.Main : Starting Main using Java 11.0.10 on dbyron-ltm9591.internal.salesforce.com with PID 75718 (/Users/dbyron/src/spinnaker/halyard/halyard-web/build/classes/java/main started by dbyron in /Users/dbyron/src/spinnaker/halyard/halyard-web) 2022-10-26 14:17:00.759 INFO 75718 --- [ main] com.netflix.spinnaker.halyard.Main : The following profiles are active: composite,test,local WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by org.codehaus.groovy.reflection.CachedClass (file:/Users/dbyron/.gradle/caches/modules-2/files-2.1/org.codehaus.groovy/groovy/2.5.15/85c14d7031ae2bfd1d0bbed513ebddcc3a530633/groovy-2.5.15.jar) to method java.lang.Object.finalize() WARNING: Please consider reporting this to the maintainers of org.codehaus.groovy.reflection.CachedClass WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release 2022-10-26 14:17:02.134 INFO 75718 --- [ main] o.s.c.a.ConfigurationClassParser : Properties location [file:/opt/spinnaker/hal.properties] not resolvable: /opt/spinnaker/hal.properties (No such file or directory) 2022-10-26 14:17:03.450 ERROR 75718 --- [ main] o.s.boot.SpringApplication : Application run failed java.lang.IllegalStateException: Error processing condition on org.springframework.cloud.config.server.config.CompositeRepositoryConfiguration.searchPathCompositeEnvironmentRepository at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60) ~[spring-boot-autoconfigure-2.4.13.jar:2.4.13] at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108) ~[spring-context-5.3.13.jar:5.3.13] at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:193) ~[spring-context-5.3.13.jar:5.3.13] at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:153) ~[spring-context-5.3.13.jar:5.3.13] at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:129) ~[spring-context-5.3.13.jar:5.3.13] at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:343) ~[spring-context-5.3.13.jar:5.3.13] at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:247) ~[spring-context-5.3.13.jar:5.3.13] at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:311) ~[spring-context-5.3.13.jar:5.3.13] at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:112) ~[spring-context-5.3.13.jar:5.3.13] at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746) ~[spring-context-5.3.13.jar:5.3.13] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564) ~[spring-context-5.3.13.jar:5.3.13] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.13.jar:2.4.13] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:771) ~[spring-boot-2.4.13.jar:2.4.13] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:763) ~[spring-boot-2.4.13.jar:2.4.13] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:438) ~[spring-boot-2.4.13.jar:2.4.13] at org.springframework.boot.SpringApplication.run(SpringApplication.java:339) ~[spring-boot-2.4.13.jar:2.4.13] at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:144) ~[spring-boot-2.4.13.jar:2.4.13] at com.netflix.spinnaker.halyard.Main.main(Main.java:38) ~[main/:na] Caused by: java.util.NoSuchElementException: No value bound at org.springframework.boot.context.properties.bind.BindResult.get(BindResult.java:55) ~[spring-boot-2.4.13.jar:2.4.13] at org.springframework.cloud.config.server.composite.CompositeUtils.getCompositeTypeList(CompositeUtils.java:51) ~[spring-cloud-config-server-3.0.6.jar:3.0.6] at org.springframework.cloud.config.server.composite.OnSearchPathLocatorPresent.getMatchOutcome(OnSearchPathLocatorPresent.java:40) ~[spring-cloud-config-server-3.0.6.jar:3.0.6] at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47) ~[spring-boot-autoconfigure-2.4.13.jar:2.4.13] ... 17 common frames omitted > Task :halyard-web:run FAILED Including org.springframework.cloud:spring-cloud-starter-bootstrap as a runtime dependencies enables the functionality that https://github.com/spring-cloud/spring-cloud-release/wiki/Spring-Cloud-2020.0-Release-Notes#breaking-changes-1 mentions regarding bootstrap functionality from spring-cloud-commons See https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.4-Release-Notes#config-data-imports for background on spring.config.on-not-found=ignore. Without it (and with spring-cloud-starter-bootstrap), halyard-web:run still fails: $ ./gradlew halyard-web:run > Task :halyard-web:run FAILED 14:27:19.752 [main] DEBUG org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter - Application failed to start due to an exception org.springframework.boot.context.config.ConfigDataLocationNotFoundException: Config data location '/opt/spinnaker/config/' cannot be found at org.springframework.boot.context.config.ConfigDataEnvironment.checkMandatoryLocations(ConfigDataEnvironment.java:383) at org.springframework.boot.context.config.ConfigDataEnvironment.applyToEnvironment(ConfigDataEnvironment.java:326) at org.springframework.boot.context.config.ConfigDataEnvironment.processAndApply(ConfigDataEnvironment.java:233) at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:102) at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:94) at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEnvironmentPreparedEvent(EnvironmentPostProcessorApplicationListener.java:100) at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEvent(EnvironmentPostProcessorApplicationListener.java:86) at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176) at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:131) at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:82) at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:63) at java.base/java.util.ArrayList.forEach(ArrayList.java:1541) at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:117) at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:111) at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:62) at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:375) at org.springframework.boot.SpringApplication.run(SpringApplication.java:333) at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:144) at org.springframework.cloud.bootstrap.BootstrapApplicationListener.bootstrapServiceContext(BootstrapApplicationListener.java:197) at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:114) at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:77) at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176) at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:131) at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:82) at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:63) at java.base/java.util.ArrayList.forEach(ArrayList.java:1541) at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:117) at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:111) at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:62) at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:375) at org.springframework.boot.SpringApplication.run(SpringApplication.java:333) at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:144) at com.netflix.spinnaker.halyard.Main.main(Main.java:40) 14:27:19.756 [main] ERROR org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter - *************************** APPLICATION FAILED TO START *************************** Description: Config data location '/opt/spinnaker/config/' does not exist Action: Check that the value '/opt/spinnaker/config/' is correct, or prefix it with 'optional:' --- halyard-web/halyard-web.gradle | 2 ++ .../src/main/java/com/netflix/spinnaker/halyard/Main.java | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/halyard-web/halyard-web.gradle b/halyard-web/halyard-web.gradle index d5361587f7..598e7dd09e 100644 --- a/halyard-web/halyard-web.gradle +++ b/halyard-web/halyard-web.gradle @@ -45,6 +45,8 @@ dependencies { implementation project(':halyard-core') implementation project(':halyard-deploy') implementation project(':halyard-proto') + + runtimeOnly 'org.springframework.cloud:spring-cloud-starter-bootstrap' } def cliScript = project.tasks.create('createCliStartScripts', CreateStartScripts) { diff --git a/halyard-web/src/main/java/com/netflix/spinnaker/halyard/Main.java b/halyard-web/src/main/java/com/netflix/spinnaker/halyard/Main.java index 32e028e85d..c4dcae7ebf 100644 --- a/halyard-web/src/main/java/com/netflix/spinnaker/halyard/Main.java +++ b/halyard-web/src/main/java/com/netflix/spinnaker/halyard/Main.java @@ -31,7 +31,8 @@ @EnableAutoConfiguration @EnableConfigServer public class Main extends SpringBootServletInitializer { - private static final Map DEFAULT_PROPS = new DefaultPropertiesBuilder().build(); + private static final Map DEFAULT_PROPS = + new DefaultPropertiesBuilder().property("spring.config.on-not-found", "ignore").build(); public static void main(String... args) { ConfigServerBootstrap.systemProperties("halyard");