Repository: quarkusio/quarkus
Issue: Combination of quarkus-resteasy,quarkus-spring-data-rest ends with "Cannot generate HAL endpoints"

### Describe the bug

Combination of `quarkus-resteasy,quarkus-spring-data-rest` ends with "Cannot generate HAL endpoints"

HAL was introduced in https://github.com/quarkusio/quarkus/pull/25396/files by @Sgitario 

```
2022-06-23 15:16:56,114 INFO  [org.jbo.threads] (main) JBoss Threads version 3.4.2.Final
2022-06-23 15:16:56,160 WARN  [io.qua.agr.dep.AgroalProcessor] (build-32) The Agroal dependency is present but no JDBC datasources have been defined.
2022-06-23 15:16:56,320 INFO  [io.qua.dep.dev.IsolatedDevModeMain] (main) Attempting to start live reload endpoint to recover from previous Quarkus startup failure
2022-06-23 15:16:56,487 INFO  [org.jbo.threads] (main) JBoss Threads version 3.4.2.Final
2022-06-23 15:16:56,678 ERROR [io.qua.dep.dev.IsolatedDevModeMain] (main) Failed to start quarkus: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
	[error]: Build step io.quarkus.resteasy.links.deployment.LinksProcessor#addHalSupport threw an exception: java.lang.IllegalStateException: Cannot generate HAL endpoints without either 'quarkus-resteasy-jsonb' or 'quarkus-resteasy-jackson'
	at io.quarkus.resteasy.links.deployment.LinksProcessor.addHalSupport(LinksProcessor.java:20)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:944)
	at io.quarkus.builder.BuildContext.run(BuildContext.java:277)
	at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
	at java.base/java.lang.Thread.run(Thread.java:829)
	at org.jboss.threads.JBossThread.run(JBossThread.java:501)

	at io.quarkus.runner.bootstrap.AugmentActionImpl.runAugment(AugmentActionImpl.java:330)
	at io.quarkus.runner.bootstrap.AugmentActionImpl.createInitialRuntimeApplication(AugmentActionImpl.java:252)
	at io.quarkus.runner.bootstrap.AugmentActionImpl.createInitialRuntimeApplication(AugmentActionImpl.java:60)
	at io.quarkus.deployment.dev.IsolatedDevModeMain.firstStart(IsolatedDevModeMain.java:95)
	at io.quarkus.deployment.dev.IsolatedDevModeMain.accept(IsolatedDevModeMain.java:485)
	at io.quarkus.deployment.dev.IsolatedDevModeMain.accept(IsolatedDevModeMain.java:68)
	at io.quarkus.bootstrap.app.CuratedApplication.runInCl(CuratedApplication.java:147)
	at io.quarkus.bootstrap.app.CuratedApplication.runInAugmentClassLoader(CuratedApplication.java:102)
	at io.quarkus.deployment.dev.DevModeMain.start(DevModeMain.java:131)
	at io.quarkus.deployment.dev.DevModeMain.main(DevModeMain.java:62)
Caused by: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
	[error]: Build step io.quarkus.resteasy.links.deployment.LinksProcessor#addHalSupport threw an exception: java.lang.IllegalStateException: Cannot generate HAL endpoints without either 'quarkus-resteasy-jsonb' or 'quarkus-resteasy-jackson'
	at io.quarkus.resteasy.links.deployment.LinksProcessor.addHalSupport(LinksProcessor.java:20)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:944)
	at io.quarkus.builder.BuildContext.run(BuildContext.java:277)
	at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
	at java.base/java.lang.Thread.run(Thread.java:829)
	at org.jboss.threads.JBossThread.run(JBossThread.java:501)

	at io.quarkus.builder.Execution.run(Execution.java:116)
	at io.quarkus.builder.BuildExecutionBuilder.execute(BuildExecutionBuilder.java:79)
	at io.quarkus.deployment.QuarkusAugmentor.run(QuarkusAugmentor.java:157)
	at io.quarkus.runner.bootstrap.AugmentActionImpl.runAugment(AugmentActionImpl.java:328)
	... 9 more
Caused by: java.lang.IllegalStateException: Cannot generate HAL endpoints without either 'quarkus-resteasy-jsonb' or 'quarkus-resteasy-jackson'
	at io.quarkus.resteasy.links.deployment.LinksProcessor.addHalSupport(LinksProcessor.java:20)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:944)
	at io.quarkus.builder.BuildContext.run(BuildContext.java:277)
	at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
	at java.base/java.lang.Thread.run(Thread.java:829)
	at org.jboss.threads.JBossThread.run(JBossThread.java:501)
```

### Expected behavior

No error is thrown, I'm not using HAL at all.

### Actual behavior

Error when building the app

### How to Reproduce?

quarkus create app app -x quarkus-resteasy,quarkus-spring-data-rest
cd app
quarkus dev

### Output of `uname -a` or `ver`

macOS Monterey

### Output of `java -version`

Java 17

### GraalVM version (if different from Java)

_No response_

### Quarkus version or git rev

2.10.0.Final

### Build tool (ie. output of `mvnw --version` or `gradlew --version`)

_No response_

### Additional information

_No response_

Changed files:
extensions/resteasy-reactive/quarkus-resteasy-reactive-links/deployment/src/main/java/io/quarkus/resteasy/reactive/links/deployment/LinksProcessor.java
extensions/resteasy-classic/resteasy-common/deployment/src/main/java/io/quarkus/resteasy/common/deployment/ResteasyCommonProcessor.java
extensions/resteasy-classic/resteasy-links/deployment/src/main/java/io/quarkus/resteasy/links/deployment/LinksProcessor.java

diff --git a/extensions/resteasy-classic/resteasy-common/deployment/src/main/java/io/quarkus/resteasy/common/deployment/ResteasyCommonProcessor.java b/extensions/resteasy-classic/resteasy-common/deployment/src/main/java/io/quarkus/resteasy/common/deployment/ResteasyCommonProcessor.java
index 4473273519d..0d44455ea08 100644
--- a/extensions/resteasy-classic/resteasy-common/deployment/src/main/java/io/quarkus/resteasy/common/deployment/ResteasyCommonProcessor.java
+++ b/extensions/resteasy-classic/resteasy-common/deployment/src/main/java/io/quarkus/resteasy/common/deployment/ResteasyCommonProcessor.java
@@ -96,6 +96,8 @@ public class ResteasyCommonProcessor {
     private static final DotName QUARKUS_JSONB_SERIALIZER = DotName
             .createSimple("io.quarkus.resteasy.common.runtime.jsonb.QuarkusJsonbSerializer");
 
+    private static final String APPLICATION_HAL_JSON = "application/hal+json";
+
     private static final String[] WILDCARD_MEDIA_TYPE_ARRAY = { MediaType.WILDCARD };
 
     private ResteasyCommonConfig resteasyCommonConfig;
@@ -217,7 +219,8 @@ JaxrsProvidersToRegisterBuildItem setupProviders(BuildProducer<ReflectiveClassBu
             boolean needJsonSupport = restJsonSupportNeeded(indexBuildItem, ResteasyDotNames.CONSUMES)
                     || restJsonSupportNeeded(indexBuildItem, ResteasyDotNames.PRODUCES)
                     || restJsonSupportNeeded(indexBuildItem, ResteasyDotNames.RESTEASY_SSE_ELEMENT_TYPE)
-                    || restJsonSupportNeeded(indexBuildItem, ResteasyDotNames.RESTEASY_PART_TYPE);
+                    || restJsonSupportNeeded(indexBuildItem, ResteasyDotNames.RESTEASY_PART_TYPE)
+                    || restJsonSupportNeededForHalCapability(capabilities, indexBuildItem);
             if (needJsonSupport) {
                 LOGGER.warn(
                         "Quarkus detected the need of REST JSON support but you have not provided the necessary JSON " +
@@ -390,21 +393,36 @@ private void checkProperConfigAccessInProvider(AnnotationInstance instance) {
         }
     }
 
+    private boolean restJsonSupportNeededForHalCapability(Capabilities capabilities, CombinedIndexBuildItem indexBuildItem) {
+        return capabilities.isPresent(Capability.HAL)
+                && isMediaTypeFoundInAnnotation(indexBuildItem, ResteasyDotNames.PRODUCES, APPLICATION_HAL_JSON);
+    }
+
     private boolean restJsonSupportNeeded(CombinedIndexBuildItem indexBuildItem, DotName mediaTypeAnnotation) {
+        return isMediaTypeFoundInAnnotation(indexBuildItem, mediaTypeAnnotation,
+                MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_PATCH_JSON);
+    }
+
+    private boolean isMediaTypeFoundInAnnotation(CombinedIndexBuildItem indexBuildItem, DotName mediaTypeAnnotation,
+            String... mediaTypes) {
         for (AnnotationInstance annotationInstance : indexBuildItem.getIndex().getAnnotations(mediaTypeAnnotation)) {
             final AnnotationValue annotationValue = annotationInstance.value();
             if (annotationValue == null) {
                 continue;
             }
 
-            List<String> mediaTypes = Collections.emptyList();
+            List<String> foundMediaTypes = Collections.emptyList();
             if (annotationValue.kind() == Kind.ARRAY) {
-                mediaTypes = Arrays.asList(annotationValue.asStringArray());
+                foundMediaTypes = Arrays.asList(annotationValue.asStringArray());
             } else if (annotationValue.kind() == Kind.STRING) {
-                mediaTypes = Collections.singletonList(annotationValue.asString());
+                foundMediaTypes = Collections.singletonList(annotationValue.asString());
+            }
+
+            for (int i = 0; i < mediaTypes.length; i++) {
+                if (foundMediaTypes.contains(mediaTypes[i])) {
+                    return true;
+                }
             }
-            return mediaTypes.contains(MediaType.APPLICATION_JSON)
-                    || mediaTypes.contains(MediaType.APPLICATION_JSON_PATCH_JSON);
         }
 
         return false;
diff --git a/extensions/resteasy-classic/resteasy-links/deployment/src/main/java/io/quarkus/resteasy/links/deployment/LinksProcessor.java b/extensions/resteasy-classic/resteasy-links/deployment/src/main/java/io/quarkus/resteasy/links/deployment/LinksProcessor.java
index f972525e283..7829b37caae 100644
--- a/extensions/resteasy-classic/resteasy-links/deployment/src/main/java/io/quarkus/resteasy/links/deployment/LinksProcessor.java
+++ b/extensions/resteasy-classic/resteasy-links/deployment/src/main/java/io/quarkus/resteasy/links/deployment/LinksProcessor.java
@@ -15,12 +15,6 @@ void addHalSupport(Capabilities capabilities, BuildProducer<ResteasyJaxrsProvide
             BuildProducer<AdditionalBeanBuildItem> additionalBeans) {
         boolean isHalSupported = capabilities.isPresent(Capability.HAL);
         if (isHalSupported) {
-            if (!capabilities.isPresent(Capability.RESTEASY_JSON_JSONB)
-                    && !capabilities.isPresent(Capability.RESTEASY_JSON_JACKSON)) {
-                throw new IllegalStateException("Cannot generate HAL endpoints without "
-                        + "either 'quarkus-resteasy-jsonb' or 'quarkus-resteasy-jackson'");
-            }
-
             jaxRsProviders.produce(
                     new ResteasyJaxrsProviderBuildItem(HalServerResponseFilter.class.getName()));
 
diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-links/deployment/src/main/java/io/quarkus/resteasy/reactive/links/deployment/LinksProcessor.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-links/deployment/src/main/java/io/quarkus/resteasy/reactive/links/deployment/LinksProcessor.java
index 939dfdb14d2..2cdbfff1adc 100644
--- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-links/deployment/src/main/java/io/quarkus/resteasy/reactive/links/deployment/LinksProcessor.java
+++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-links/deployment/src/main/java/io/quarkus/resteasy/reactive/links/deployment/LinksProcessor.java
@@ -14,6 +14,7 @@
 import org.jboss.jandex.DotName;
 import org.jboss.jandex.FieldInfo;
 import org.jboss.jandex.IndexView;
+import org.jboss.resteasy.reactive.common.util.RestMediaType;
 
 import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
 import io.quarkus.deployment.Capabilities;
@@ -82,16 +83,25 @@ AdditionalBeanBuildItem registerRestLinksProviderProducer() {
     }
 
     @BuildStep
-    void addHalSupport(Capabilities capabilities, BuildProducer<CustomContainerResponseFilterBuildItem> customResponseFilters,
-            BuildProducer<AdditionalBeanBuildItem> additionalBeans) {
+    void validateJsonNeededForHal(Capabilities capabilities,
+            ResteasyReactiveResourceMethodEntriesBuildItem resourceMethodEntriesBuildItem) {
         boolean isHalSupported = capabilities.isPresent(Capability.HAL);
-        if (isHalSupported) {
+        if (isHalSupported && isHalMediaTypeUsedInAnyResource(resourceMethodEntriesBuildItem.getEntries())) {
+
             if (!capabilities.isPresent(Capability.RESTEASY_REACTIVE_JSON_JSONB) && !capabilities.isPresent(
                     Capability.RESTEASY_REACTIVE_JSON_JACKSON)) {
                 throw new IllegalStateException("Cannot generate HAL endpoints without "
                         + "either 'quarkus-resteasy-reactive-jsonb' or 'quarkus-resteasy-reactive-jackson'");
             }
+        }
+    }
 
+    @BuildStep
+    void addHalSupport(Capabilities capabilities,
+            BuildProducer<CustomContainerResponseFilterBuildItem> customResponseFilters,
+            BuildProducer<AdditionalBeanBuildItem> additionalBeans) {
+        boolean isHalSupported = capabilities.isPresent(Capability.HAL);
+        if (isHalSupported) {
             customResponseFilters.produce(
                     new CustomContainerResponseFilterBuildItem(HalServerResponseFilter.class.getName()));
 
@@ -99,6 +109,18 @@ void addHalSupport(Capabilities capabilities, BuildProducer<CustomContainerRespo
         }
     }
 
+    private boolean isHalMediaTypeUsedInAnyResource(List<ResteasyReactiveResourceMethodEntriesBuildItem.Entry> entries) {
+        for (ResteasyReactiveResourceMethodEntriesBuildItem.Entry entry : entries) {
+            for (String mediaType : entry.getResourceMethod().getProduces()) {
+                if (RestMediaType.APPLICATION_HAL_JSON.equals(mediaType)) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
     private LinksContainer getLinksContainer(ResteasyReactiveResourceMethodEntriesBuildItem resourceMethodEntriesBuildItem,
             IndexView index) {
         LinksContainerFactory linksContainerFactory = new LinksContainerFactory();