From da391834f2c69a0596c2fbf7b5d5b1a44c0bf846 Mon Sep 17 00:00:00 2001 From: Anjum Fatima Date: Thu, 9 Nov 2023 14:00:19 -0600 Subject: [PATCH 1/3] Documenting behavior of config inside the application when no default value is set before checkpoint --- modules/ROOT/pages/instanton-limitations.adoc | 69 ++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/modules/ROOT/pages/instanton-limitations.adoc b/modules/ROOT/pages/instanton-limitations.adoc index 1566497449..661767bb4d 100644 --- a/modules/ROOT/pages/instanton-limitations.adoc +++ b/modules/ROOT/pages/instanton-limitations.adoc @@ -1,4 +1,4 @@ -// Copyright (c) 2022 IBM Corporation and others. +// Copyright (c) 2022, 2023 IBM Corporation and others. // Licensed under Creative Commons Attribution-NoDerivatives // 4.0 International (CC BY-ND 4.0) // https://creativecommons.org/licenses/by-nd/4.0/ @@ -23,6 +23,7 @@ The following sections describe the limitations and known issues with using Open - <<#trans-before, Jakarta Transaction before checkpoint>> - <<#mp-config, Accessing MicroProfile Configuration too early>> - <<#datasource, Injecting a DataSource too early>> +- <<#mp-config-no-default, Accessing microprofile config with no default value at Checkpoint>> - <<#features, Using product extensions, user features, or features that are not supported by InstantOn>> - <<#boot,Updating configuration with a bootstrap.properties file>> - <<#securitymanager, Java SecurityManager is not supported>> @@ -161,6 +162,72 @@ This configuration uses placeholder values for things like the database name, ho If an application is injected with a `DataSource` before the checkpoint and the configuration of the `DataSource` changes, the application is restarted when the InstantOn application container image is run with the updated configuration. You can avoid this scenario by using the `beforeAppStart` option or by modifying the component not to be early startup code. In this example, that modification is to remove the `loadOnStartup = 1` attribute. +[#mp-config-no-default] +== Accessing microprofile config with no default value at Checkpoint +The configuration property can be introduced inside the application either statically through `` or `Optional`, or dynamically using a `Provider`. The following example shows ways to inject static, static-optional, dynamic and dynamic-optional config property. +[source,java] +---- + @Inject + @ConfigProperty(name = "static_config") + String staticConfig; + + @Inject + @ConfigProperty(name = "static_optional_config") + Optional staticOptionalConfig; + + @Inject + @ConfigProperty(name = "dynamic_config") + Provider dynamicConfig; + + @Inject + @ConfigProperty(name = "dynamic_optional_config") + Provider> dynamicOptionalConfig; +---- +The injected `static_config` will cause an error like the following example if there is no value found in an existing config source during checkpoint. + +[source,sh] +---- +SRCFG02000: Failed to Inject @ConfigProperty for key static_config into io.example.Example.staticConfig since the config property could not be found in any config source. +---- + +This error can be avoided by providing a default value for the configuration key in one of the following ways: + +Specify the default value on the @ConfigProperty annotation like the following: +[source,java] +---- + @Inject + @ConfigProperty(name = "static_config", defaultValue = "defaultValue") + String staticConfig; +---- + +Specify the default value in the application `META-INF/microprofile-config.properties` resource. +[source,sh] +---- + static_config=defaultValue +---- + +Specify a default value in a server.xml variable. +[source,xml] +---- + +---- + +The `defaultValue` can then be overridden on restore by configuring the value with an environment variable or values from the variable source directory. + +However, if no default value is set, we can still avoid the above error by injecting config using `static_optional_config`, `dynamic_config`, `dynamic_optional_config`. But caution is needed for CDI beans that are `@ApplicationScoped` which are created during application startup when using the afterAppStart checkpoint option. Trying to access the `dynamic_config` early during the application startup at checkpoint can cause the following error: +[source,sh] +---- +java.util.NoSuchElementException: SRCFG00014: The config property dynamic_config is required but it could not be found in any config source. +---- +While accessing the `static_optional_config` and `dynamic_optional_config` can cause the following error: +[source,sh] +---- +java.util.NoSuchElementException: No value present +---- + +Therefore, it is advisable to have a default value set for injected config properties in order to avoid the above mentioned errors. Furthermore, if the @ConfigProperty injection site is not using dynamic config then any default value injected into the application scoped bean before checkpoint will not be updated on restore. This is already mentioned in the docs at xref:#mp-config[Accessing MicroProfile Config too early] + + [#features] == Using product extensions, user features, or features that are not supported by InstantOn InstantOn supports only a subset of Open Liberty features, as described in xref:instanton.adoc#supported-features[Open Liberty InstantOn supported features]. Any public features that are enabled outside of the supported set of features for InstantOn cause checkpoint to fail with an error message like the following example: From ded697f76ecb334681fdefb340db3fbac96670a1 Mon Sep 17 00:00:00 2001 From: Anjum Fatima Date: Wed, 6 Dec 2023 11:08:59 -0600 Subject: [PATCH 2/3] Address review comments --- modules/ROOT/pages/instanton-limitations.adoc | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/modules/ROOT/pages/instanton-limitations.adoc b/modules/ROOT/pages/instanton-limitations.adoc index 661767bb4d..0b7f8a2d77 100644 --- a/modules/ROOT/pages/instanton-limitations.adoc +++ b/modules/ROOT/pages/instanton-limitations.adoc @@ -23,7 +23,7 @@ The following sections describe the limitations and known issues with using Open - <<#trans-before, Jakarta Transaction before checkpoint>> - <<#mp-config, Accessing MicroProfile Configuration too early>> - <<#datasource, Injecting a DataSource too early>> -- <<#mp-config-no-default, Accessing microprofile config with no default value at Checkpoint>> +- <<#mp-config-no-default, Accessing MicroProfile Configuration with no default value at Checkpoint>> - <<#features, Using product extensions, user features, or features that are not supported by InstantOn>> - <<#boot,Updating configuration with a bootstrap.properties file>> - <<#securitymanager, Java SecurityManager is not supported>> @@ -163,8 +163,10 @@ This configuration uses placeholder values for things like the database name, ho If an application is injected with a `DataSource` before the checkpoint and the configuration of the `DataSource` changes, the application is restarted when the InstantOn application container image is run with the updated configuration. You can avoid this scenario by using the `beforeAppStart` option or by modifying the component not to be early startup code. In this example, that modification is to remove the `loadOnStartup = 1` attribute. [#mp-config-no-default] -== Accessing microprofile config with no default value at Checkpoint -The configuration property can be introduced inside the application either statically through `` or `Optional`, or dynamically using a `Provider`. The following example shows ways to inject static, static-optional, dynamic and dynamic-optional config property. +== Accessing MicroProfile Configuration with no default value at Checkpoint +An application injected with a configuration property that has no default value set in any configuration source during checkpoint could cause some errors. This section provides the different types of error that are encountered and the remedy to fix those errors. + +A configuration property can be introduced into the application either statically or dynamically, and in either case, the property can be declared optional. The following example shows ways to inject static, static-optional, dynamic, and dynamic-optional configuration properties. [source,java] ---- @Inject @@ -183,16 +185,16 @@ The configuration property can be introduced inside the application either stati @ConfigProperty(name = "dynamic_optional_config") Provider> dynamicOptionalConfig; ---- -The injected `static_config` will cause an error like the following example if there is no value found in an existing config source during checkpoint. +If no value is found in an existing configuration source during checkpoint, the injected `static_config` property causes an error similar to the following example: [source,sh] ---- SRCFG02000: Failed to Inject @ConfigProperty for key static_config into io.example.Example.staticConfig since the config property could not be found in any config source. ---- -This error can be avoided by providing a default value for the configuration key in one of the following ways: +You can avoid this error by providing a default value for the configuration key in one of the following ways: -Specify the default value on the @ConfigProperty annotation like the following: +Specify the default value on the `@ConfigProperty` annotation:: [source,java] ---- @Inject @@ -200,32 +202,31 @@ Specify the default value on the @ConfigProperty annotation like the following: String staticConfig; ---- -Specify the default value in the application `META-INF/microprofile-config.properties` resource. +Specify the default value in the application `META-INF/microprofile-config.properties` resource:: [source,sh] ---- static_config=defaultValue ---- -Specify a default value in a server.xml variable. +Specify a default value in a `variable` element in the server.xml` file:: [source,xml] ---- ---- -The `defaultValue` can then be overridden on restore by configuring the value with an environment variable or values from the variable source directory. - -However, if no default value is set, we can still avoid the above error by injecting config using `static_optional_config`, `dynamic_config`, `dynamic_optional_config`. But caution is needed for CDI beans that are `@ApplicationScoped` which are created during application startup when using the afterAppStart checkpoint option. Trying to access the `dynamic_config` early during the application startup at checkpoint can cause the following error: +If no default value is set, you can still avoid the previous error by injecting configuration with the `static_optional_config`, `dynamic_config`, or `dynamic_optional_config` properties. +However, the following error might occur if you use the checkpoint option with CDI beans that are `@ApplicationScoped` and the `dynamic_config` is accessed too early during application startup: [source,sh] ---- java.util.NoSuchElementException: SRCFG00014: The config property dynamic_config is required but it could not be found in any config source. ---- -While accessing the `static_optional_config` and `dynamic_optional_config` can cause the following error: +Similarly, accessing the `static_optional_config` and `dynamic_optional_config` too early might cause the following error: [source,sh] ---- java.util.NoSuchElementException: No value present ---- -Therefore, it is advisable to have a default value set for injected config properties in order to avoid the above mentioned errors. Furthermore, if the @ConfigProperty injection site is not using dynamic config then any default value injected into the application scoped bean before checkpoint will not be updated on restore. This is already mentioned in the docs at xref:#mp-config[Accessing MicroProfile Config too early] +Therefore, to avoid these errors it is best to set a default value for injected config properties as optional and dynamic config can be accessed too early during application startup. Furthermore, if the `@ConfigProperty` injection site is not using dynamic configuration, then any default value that is injected into the application-scoped bean before checkpoint is not updated on restore. For more information, see xref:#mp-config[Accessing MicroProfile Config too early] [#features] From 177c3e97b7e5a9683bc037ce76ba025c429bd056 Mon Sep 17 00:00:00 2001 From: Anjum Fatima Date: Thu, 7 Dec 2023 12:27:37 -0600 Subject: [PATCH 3/3] Address ID review comments --- modules/ROOT/pages/instanton-limitations.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/ROOT/pages/instanton-limitations.adoc b/modules/ROOT/pages/instanton-limitations.adoc index 0b7f8a2d77..853687aef5 100644 --- a/modules/ROOT/pages/instanton-limitations.adoc +++ b/modules/ROOT/pages/instanton-limitations.adoc @@ -23,7 +23,7 @@ The following sections describe the limitations and known issues with using Open - <<#trans-before, Jakarta Transaction before checkpoint>> - <<#mp-config, Accessing MicroProfile Configuration too early>> - <<#datasource, Injecting a DataSource too early>> -- <<#mp-config-no-default, Accessing MicroProfile Configuration with no default value at Checkpoint>> +- <<#mp-config-no-default, Accessing MicroProfile Config properties with no default value at checkpoint>> - <<#features, Using product extensions, user features, or features that are not supported by InstantOn>> - <<#boot,Updating configuration with a bootstrap.properties file>> - <<#securitymanager, Java SecurityManager is not supported>> @@ -163,8 +163,8 @@ This configuration uses placeholder values for things like the database name, ho If an application is injected with a `DataSource` before the checkpoint and the configuration of the `DataSource` changes, the application is restarted when the InstantOn application container image is run with the updated configuration. You can avoid this scenario by using the `beforeAppStart` option or by modifying the component not to be early startup code. In this example, that modification is to remove the `loadOnStartup = 1` attribute. [#mp-config-no-default] -== Accessing MicroProfile Configuration with no default value at Checkpoint -An application injected with a configuration property that has no default value set in any configuration source during checkpoint could cause some errors. This section provides the different types of error that are encountered and the remedy to fix those errors. +== Accessing MicroProfile Config properties with no default value at checkpoint +An application injected with a configuration property that has no default value set in any configuration source might cause errors during checkpoint. This section provides solutions for common errors that are encountered. A configuration property can be introduced into the application either statically or dynamically, and in either case, the property can be declared optional. The following example shows ways to inject static, static-optional, dynamic, and dynamic-optional configuration properties. [source,java]