Repository: quarkusio/quarkus
Issue: `StorkClientRequestFilter` not registered when using `ClientBuilder` to build a jax-rs client

### Describe the bug

When using Stork with a manually-created jax-rs client (via `ClientBuilder.newClient()`), the `StorkClientRequestFilter` is not automatically registered.

Stork worked fine with the jax-rs client in Quarkus 2.12, but in 2.13 this is broken unless the user manually registers the filter.

See https://github.com/quarkusio/quarkus-super-heroes/blob/main/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/VillainClient.java#L38

If the user does not manually register the filter then they will end up with a failure that looks something like

```
java.lang.IllegalArgumentException: Invalid REST Client URL used: 'stork://villain-service/api/villains/random'
```

At a very minimum, this should be documented in the Quarkus 2.13 release notes.

### Expected behavior

I would expect Stork to "just work" with the jax-rs client, as it did prior to Quarkus 2.12.

### Actual behavior

The application fails if the user does not manually register the filter.

### How to Reproduce?

_No response_

### 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

_No response_

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

_No response_

### Additional information

The `OpenTelemetryClientFilter` seems to be registered automatically when creating the jax-rs client this way, so there must be a way to do this as well for the `StorkClientRequestFilter`.

Changed files:
independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/WebTargetImpl.java
extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/stork/StorkIntegrationTest.java

diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/stork/StorkIntegrationTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/stork/StorkIntegrationTest.java
index f57a1d437d7..32c92031137 100644
--- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/stork/StorkIntegrationTest.java
+++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/stork/StorkIntegrationTest.java
@@ -4,6 +4,10 @@
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import java.net.URI;
+import java.net.URISyntaxException;
+
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.core.UriBuilder;
 
 import org.eclipse.microprofile.rest.client.RestClientBuilder;
 import org.eclipse.microprofile.rest.client.inject.RestClient;
@@ -34,6 +38,19 @@ void shouldDetermineUrlViaStork() {
         assertThat(greeting).isEqualTo("hello, black and white bird");
     }
 
+    @Test
+    void shouldDetermineUrlViaStorkWhenUsingTarget() throws URISyntaxException {
+        String greeting = ClientBuilder.newClient().target("stork://hello-service/hello").request().get(String.class);
+        assertThat(greeting).isEqualTo("Hello");
+
+        greeting = ClientBuilder.newClient().target(new URI("stork://hello-service/hello")).request().get(String.class);
+        assertThat(greeting).isEqualTo("Hello");
+
+        greeting = ClientBuilder.newClient().target(UriBuilder.fromUri("stork://hello-service/hello")).request()
+                .get(String.class);
+        assertThat(greeting).isEqualTo("Hello");
+    }
+
     @Test
     void shouldDetermineUrlViaStorkCDI() {
         String greeting = client.echo("big bird");
diff --git a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/WebTargetImpl.java b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/WebTargetImpl.java
index 56fc7d2f4d0..1b4b0355ae6 100644
--- a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/WebTargetImpl.java
+++ b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/WebTargetImpl.java
@@ -320,10 +320,45 @@ private void abortIfClosed() {
 
     protected InvocationBuilderImpl createQuarkusRestInvocationBuilder(HttpClient client, UriBuilder uri,
             ConfigurationImpl configuration) {
-        return new InvocationBuilderImpl(uri.build(), restClient, client, this, configuration,
+        URI actualUri = uri.build();
+        registerStorkFilterIfNeeded(configuration, actualUri);
+        return new InvocationBuilderImpl(actualUri, restClient, client, this, configuration,
                 handlerChain.setPreClientSendHandler(preClientSendHandler), requestContext);
     }
 
+    /**
+     * If the URI starts with stork:// or storks://, then register the StorkClientRequestFilter automatically.
+     *
+     * @param configuration the configuration
+     * @param actualUri the uri
+     */
+    private static void registerStorkFilterIfNeeded(ConfigurationImpl configuration, URI actualUri) {
+        if (actualUri.getScheme() != null && actualUri.getScheme().startsWith("stork")
+                && !isStorkAlreadyRegistered(configuration)) {
+            configuration.register(StorkClientRequestFilter.class);
+        }
+    }
+
+    /**
+     * Checks if the Stork request filter is already registered.
+     * We cannot use configuration.isRegistered, as the user registration uses a subclass, and so fail the equality
+     * expectation.
+     * <p>
+     * This method prevents having the stork filter registered twice: once because the uri starts with stork:// and,
+     * once from the user.
+     *
+     * @param configuration the configuration
+     * @return {@code true} if stork is already registered.
+     */
+    private static boolean isStorkAlreadyRegistered(ConfigurationImpl configuration) {
+        for (Class<?> clazz : configuration.getClasses()) {
+            if (clazz.getName().startsWith(StorkClientRequestFilter.class.getName())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     @Override
     public WebTargetImpl property(String name, Object value) {
         abortIfClosed();