diff --git a/core/deployment/src/main/java/io/quarkus/deployment/Capability.java b/core/deployment/src/main/java/io/quarkus/deployment/Capability.java index 507116e713a24..79b8cafffe276 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/Capability.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/Capability.java @@ -80,6 +80,7 @@ public interface Capability { String QUARTZ = QUARKUS_PREFIX + "quartz"; String KUBERNETES_SERVICE_BINDING = QUARKUS_PREFIX + "kubernetes.service.binding"; + String KUBERNETES_CLIENT = QUARKUS_PREFIX + "kubernetes.client"; /** * @deprecated diff --git a/extensions/kubernetes-client/runtime/pom.xml b/extensions/kubernetes-client/runtime/pom.xml index 56471229b8c50..762cfe6c75831 100644 --- a/extensions/kubernetes-client/runtime/pom.xml +++ b/extensions/kubernetes-client/runtime/pom.xml @@ -63,6 +63,11 @@ io.quarkus quarkus-bootstrap-maven-plugin + + + io.quarkus.kubernetes.client + + maven-compiler-plugin diff --git a/extensions/smallrye-stork/deployment/src/main/java/io/quarkus/stork/deployment/SmallRyeStorkProcessor.java b/extensions/smallrye-stork/deployment/src/main/java/io/quarkus/stork/deployment/SmallRyeStorkProcessor.java index 45d96371a0f69..4fea62e416a07 100644 --- a/extensions/smallrye-stork/deployment/src/main/java/io/quarkus/stork/deployment/SmallRyeStorkProcessor.java +++ b/extensions/smallrye-stork/deployment/src/main/java/io/quarkus/stork/deployment/SmallRyeStorkProcessor.java @@ -2,11 +2,18 @@ import static java.util.Arrays.asList; +import org.jboss.logging.Logger; + import io.quarkus.arc.deployment.SyntheticBeansRuntimeInitBuildItem; +import io.quarkus.bootstrap.classloading.QuarkusClassLoader; +import io.quarkus.builder.item.EmptyBuildItem; +import io.quarkus.deployment.Capabilities; +import io.quarkus.deployment.Capability; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.annotations.Consume; import io.quarkus.deployment.annotations.ExecutionTime; +import io.quarkus.deployment.annotations.Produce; import io.quarkus.deployment.annotations.Record; import io.quarkus.deployment.builditem.RuntimeConfigSetupCompleteBuildItem; import io.quarkus.deployment.builditem.ShutdownContextBuildItem; @@ -20,18 +27,46 @@ public class SmallRyeStorkProcessor { + private static final String KUBERNETES_SERVICE_DISCOVERY_PROVIDER = "io.smallrye.stork.servicediscovery.kubernetes.KubernetesServiceDiscoveryProvider"; + private static final Logger LOGGER = Logger.getLogger(SmallRyeStorkProcessor.class.getName()); + @BuildStep - void registerServiceProviders(BuildProducer services) { + void registerServiceProviders(BuildProducer services, Capabilities capabilities) { services.produce(new ServiceProviderBuildItem(io.smallrye.stork.spi.config.ConfigProvider.class.getName(), StorkConfigProvider.class.getName())); - for (Class providerClass : asList(LoadBalancerLoader.class, ServiceDiscoveryLoader.class)) { services.produce(ServiceProviderBuildItem.allProvidersFromClassPath(providerClass.getName())); } } + /** + * This build step is the fix for https://github.com/quarkusio/quarkus/issues/24444. + * Because Stork itself cannot depend on Quarkus, and we do not want to have extensions for all the service + * discovery and load-balancer providers, we work around the issue by detecting when the kubernetes service + * discovery is used and if the kubernetes extension is used. + */ + @BuildStep + @Produce(AlwaysBuildItem.class) + void checkThatTheKubernetesExtensionIsUsedWhenKubernetesServiceDiscoveryInOnTheClasspath(Capabilities capabilities) { + if (QuarkusClassLoader.isClassPresentAtRuntime(KUBERNETES_SERVICE_DISCOVERY_PROVIDER)) { + if (!capabilities.isPresent(Capability.KUBERNETES_CLIENT)) { + LOGGER.warn( + "The application is using the Stork Kubernetes Service Discovery provider but does not depend on the `quarkus-kubernetes-client` extension. " + + + "It is highly recommended to use the `io.quarkus:quarkus-kubernetes-client` extension with the Kubernetes service discovery. \n" + + + "To add this extension:" + + "\n - with the quarkus CLI, run: `quarkus ext add io.quarkus:quarkus-kubernetes-client`" + + "\n - with Apache Maven, run: `./mvnw quarkus:add-extension -Dextensions=\"io.quarkus:quarkus-kubernetes-client\"`" + + + "\n - or just add the `io.quarkus:quarkus-kubernetes-client` dependency to the project"); + } + } + } + @BuildStep @Record(ExecutionTime.RUNTIME_INIT) + @Consume(AlwaysBuildItem.class) @Consume(RuntimeConfigSetupCompleteBuildItem.class) @Consume(SyntheticBeansRuntimeInitBuildItem.class) void initializeStork(SmallRyeStorkRecorder storkRecorder, ShutdownContextBuildItem shutdown, VertxBuildItem vertx, @@ -39,4 +74,8 @@ void initializeStork(SmallRyeStorkRecorder storkRecorder, ShutdownContextBuildIt storkRecorder.initialize(shutdown, vertx.getVertx(), configuration); } + private static final class AlwaysBuildItem extends EmptyBuildItem { + // Just here to be sure we run the `checkThatTheKubernetesExtensionIsUsedWhenKubernetesServiceDiscoveryInOnTheClasspath` build step. + } + }