Repository: quarkusio/quarkus
Issue: Cannot resolve config property referenced in dev-console card template

### Describe the bug

I have an extension contributing a card to the dev-console. The card's `embedded.html` contains a hyperlink to an endpoint contributed by the extension like so:
```html
<a href="{config:property('quarkus.http.root-path')}foo/bar" class="badge badge-light">...</a>
```

I would have to downgrade and test again, but I am fairly certain that this used to work properly prior to Quarkus 2.5.0.

Now with Quarkus 2.5.0 the config property `quarkus.http.root-path` can no longer be resolved by the template expression `config:property('quarkus.http.root-path')`.

I did a little bit of debugging and noticed that there are a lot of `SmallRyeConfig` objects being created. A separate one is also created once the dev-console is opened and this config object does not contain the default value for `quarkus.http.root-path` and it looks like it doesn't either contain the config source for the `application.properties` file.

### Expected behavior

The `embedded.html` file for a dev-console card should be able to reference run-time config properties (and build-time config properties visible at run-time) using template expressions like `config:property('quarkus.http.root-path')`. The expression should be resolved to the value provided by the application (`application.properties`, system properties, etc.) or the default value specified by the corresponding `@BuildItem` annotated field.

### Actual behavior

The `config:property()` template expression currently doesn't appear to be working properly. I get the impression that it may be using the wrong `SmallRyeConfig` instance. The whole expression is resolved to the empty string and I couldn't see any error being logged anywhere either.

### How to Reproduce?

Creating a reproducer would cost me some time, but I could look into it.

Basically all I did was to implement a Quarkus extension where I contribute a dev-console card with an `embedded.html` file as described above.

### Output of `uname -a` or `ver`

_No response_

### Output of `java -version`

_No response_

### GraalVM version (if different from Java)

_No response_

### Quarkus version or git rev

2.5.0.Final

### Build tool (ie. output of `mvnw --version` or `gradlew --version`)

_No response_

### Additional information

_No response_

Changed files:
extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/DevConsoleRecorder.java
extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleProcessor.java

diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleProcessor.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleProcessor.java
index 14ceea76392..873c889391c 100644
--- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleProcessor.java
+++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleProcessor.java
@@ -323,6 +323,7 @@ public void runtimeTemplates(List<DevConsoleRuntimeTemplateInfoBuildItem> items,
         for (DevConsoleRuntimeTemplateInfoBuildItem i : items) {
             recorder.addInfo(i.getGroupId(), i.getArtifactId(), i.getName(), i.getObject());
         }
+        recorder.initConfigFun();
     }
 
     @BuildStep(onlyIf = IsDevelopment.class)
@@ -567,8 +568,9 @@ private Engine buildEngine(List<DevTemplatePathBuildItem> devTemplatePaths,
                 });
             } else {
                 return ctx.evaluate(params.get(0)).thenCompose(propertyName -> {
-                    String val = ConfigProvider.getConfig().getOptionalValue(propertyName.toString(), String.class)
-                            .orElse(defaultValues.get(propertyName.toString()));
+                    // Use the function stored in the DevConsoleRecorder to make sure the config is obtained using the correct TCCL
+                    Function<String, Optional<String>> configFun = DevConsoleManager.getGlobal("devui-config-fun");
+                    String val = configFun.apply(propertyName.toString()).orElse(defaultValues.get(propertyName.toString()));
                     return CompletableFuture.completedFuture(val != null ? val : Results.NotFound.from(ctx));
                 });
             }
diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/DevConsoleRecorder.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/DevConsoleRecorder.java
index 1ccfd5f276f..0242af20607 100644
--- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/DevConsoleRecorder.java
+++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/DevConsoleRecorder.java
@@ -9,15 +9,18 @@
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Optional;
 import java.util.function.Function;
 import java.util.function.Supplier;
 
+import org.eclipse.microprofile.config.ConfigProvider;
 import org.jboss.logging.Logger;
 
 import io.quarkus.dev.console.DevConsoleManager;
 import io.quarkus.dev.testing.ContinuousTestingSharedStateManager;
 import io.quarkus.runtime.ShutdownContext;
 import io.quarkus.runtime.annotations.Recorder;
+import io.smallrye.config.SmallRyeConfig;
 import io.vertx.core.Handler;
 import io.vertx.ext.web.RoutingContext;
 
@@ -38,6 +41,16 @@ public Map<String, Object> apply(String s) {
         data.put(name, supplier.get());
     }
 
+    public void initConfigFun() {
+        SmallRyeConfig config = (SmallRyeConfig) ConfigProvider.getConfig();
+        DevConsoleManager.setGlobal("devui-config-fun", new Function<String, Optional<String>>() {
+            @Override
+            public Optional<String> apply(String name) {
+                return config.getOptionalValue(name, String.class);
+            }
+        });
+    }
+
     public Handler<RoutingContext> devConsoleHandler(String devConsoleFinalDestination,
             ShutdownContext shutdownContext) {
         shutdownContext.addShutdownTask(new CleanupDevConsoleTempDirectory(devConsoleFinalDestination));