Helidon Connector 3/4 VS JDK 17/21

Signed-off-by: Maxim Nesen <maxim.nesen@oracle.com>
diff --git a/connectors/helidon-connector/pom.xml b/connectors/helidon-connector/pom.xml
index a40f5d9..fc9873e 100644
--- a/connectors/helidon-connector/pom.xml
+++ b/connectors/helidon-connector/pom.xml
@@ -93,6 +93,9 @@
             <activation>
                 <jdk>[17,21)</jdk>
             </activation>
+            <properties>
+                <helidon.connector.version>${helidon3.connector.version}</helidon.connector.version>
+            </properties>
             <build>
                 <directory>${java17.build.outputDirectory}</directory>
                 <plugins>
@@ -134,7 +137,7 @@
             <build>
                 <!-- 17 is correct, the module works with Helidon 3 supporting JDK 17, too -->
                 <!-- The build is against Helidon 4, which requires JDK 21 for the build, though -->
-                <directory>${java17.build.outputDirectory}</directory>
+                <directory>${java21.build.outputDirectory}</directory>
                 <plugins>
                     <plugin>
                         <groupId>org.codehaus.mojo</groupId>
@@ -209,7 +212,7 @@
                                 <phase>package</phase>
                                 <configuration>
                                     <target>
-                                        <property name="sources-jar" value="${java17.build.outputDirectory}/${project.artifactId}-${project.version}-sources.jar"/>
+                                        <property name="sources-jar" value="${java21.build.outputDirectory}/${project.artifactId}-${project.version}-sources.jar"/>
                                         <echo>sources-jar: ${sources-jar}</echo>
                                         <zip destfile="${sources-jar}" update="true">
                                             <zipfileset dir="${java21.sourceDirectory}" prefix="META-INF/versions/21"/>
diff --git a/connectors/helidon-connector/src/main/java17/org/glassfish/jersey/helidon/connector/Helidon3ConnectorProvider.java b/connectors/helidon-connector/src/main/java/org/glassfish/jersey/helidon/connector/Helidon3ConnectorProvider.java
similarity index 100%
rename from connectors/helidon-connector/src/main/java17/org/glassfish/jersey/helidon/connector/Helidon3ConnectorProvider.java
rename to connectors/helidon-connector/src/main/java/org/glassfish/jersey/helidon/connector/Helidon3ConnectorProvider.java
diff --git a/connectors/helidon-connector/src/main/java17/org/glassfish/jersey/helidon/connector/HelidonVersionChecker.java b/connectors/helidon-connector/src/main/java/org/glassfish/jersey/helidon/connector/HelidonVersionChecker.java
similarity index 100%
rename from connectors/helidon-connector/src/main/java17/org/glassfish/jersey/helidon/connector/HelidonVersionChecker.java
rename to connectors/helidon-connector/src/main/java/org/glassfish/jersey/helidon/connector/HelidonVersionChecker.java
diff --git a/connectors/helidon-connector/src/main/java17/org/glassfish/jersey/helidon/connector/HelidonClientProperties.java b/connectors/helidon-connector/src/main/java17/org/glassfish/jersey/helidon/connector/HelidonClientProperties.java
index b0d8401..f457327 100644
--- a/connectors/helidon-connector/src/main/java17/org/glassfish/jersey/helidon/connector/HelidonClientProperties.java
+++ b/connectors/helidon-connector/src/main/java17/org/glassfish/jersey/helidon/connector/HelidonClientProperties.java
@@ -13,17 +13,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
-
 package org.glassfish.jersey.helidon.connector;
 
-import io.helidon.common.tls.Tls;
-import io.helidon.config.Config;
-import io.helidon.webclient.api.WebClient;
 import org.glassfish.jersey.internal.util.PropertiesClass;
 
-import java.util.List;
-import java.util.Map;
-
 /**
  * Configuration options specific to the Client API that utilizes {@code HelidonConnectorProvider}
  * @since 2.31
@@ -31,60 +24,8 @@
 @PropertiesClass
 public final class HelidonClientProperties {
 
-    private HelidonClientProperties() {
-    }
-
     /**
-     * Property name to set a {@link Config} instance to by used by underlying {@link WebClient}.
-     * This property is settable on {@link jakarta.ws.rs.core.Configurable#property(String, Object)}.
-     *
-     * @see io.helidon.webclient.api.WebClientConfig.Builder#config(io.helidon.common.config.Config)
+     * A Helidon {@code Config} instance that is passed to {@code WebClient.Builder#config(Config)} if available.
      */
     public static final String CONFIG = "jersey.connector.helidon.config";
-
-    /**
-     * Property name to set a {@link Tls} instance to be used by underlying {@link WebClient}.
-     * This property is settable on {@link jakarta.ws.rs.core.Configurable#property(String, Object)}.
-     *
-     * @see io.helidon.webclient.api.WebClientConfig.Builder#tls(Tls)
-     */
-    public static final String TLS = "jersey.connector.helidon.tls";
-
-    /**
-     * Property name to set a {@code List<? extends  ProtocolConfig>} instance with a list of
-     * protocol configs to be used by underlying {@link WebClient}.
-     * This property is settable on {@link jakarta.ws.rs.core.Configurable#property(String, Object)}.
-     *
-     * @see io.helidon.webclient.api.WebClientConfig.Builder#protocolConfigs(List)
-     */
-    public static final String PROTOCOL_CONFIGS = "jersey.connector.helidon.protocolConfigs";
-
-    /**
-     * Property name to set a {@code Map<String, String>} instance with a list of
-     * default headers to be used by underlying {@link WebClient}.
-     * This property is settable on {@link jakarta.ws.rs.core.Configurable#property(String, Object)}.
-     *
-     * @see io.helidon.webclient.api.WebClientConfig.Builder#defaultHeadersMap(Map)
-     */
-    public static final String DEFAULT_HEADERS = "jersey.connector.helidon.defaultHeaders";
-
-    /**
-     * Property name to set a protocol ID for each request. You can use this property
-     * to request an HTTP/2 upgrade from HTTP/1.1 by setting its value to {@code "h2"}.
-     * When using TLS, Helidon uses negotiation via the ALPN extension instead of this
-     * property.
-     *
-     * @see io.helidon.webclient.api.HttpClientRequest#protocolId(String)
-     */
-    public static final String PROTOCOL_ID = "jersey.connector.helidon.protocolId";
-
-    /**
-     * Property name to enable or disable connection caching in the underlying {@link WebClient}.
-     * The default for the Helidon connector is {@code false}, or no sharing (which is the
-     * opposite of {@link WebClient}). Set this property to {@code true} to enable connection
-     * caching.
-     *
-     * @see io.helidon.webclient.api.WebClientConfig.Builder#shareConnectionCache(boolean)
-     */
-    public static final String SHARE_CONNECTION_CACHE = "jersey.connector.helidon.shareConnectionCache";
-}
+}
\ No newline at end of file
diff --git a/connectors/helidon-connector/src/main/java17/org/glassfish/jersey/helidon/connector/HelidonConnectorProvider.java b/connectors/helidon-connector/src/main/java17/org/glassfish/jersey/helidon/connector/HelidonConnectorProvider.java
index 6fc740c..2531a4e 100644
--- a/connectors/helidon-connector/src/main/java17/org/glassfish/jersey/helidon/connector/HelidonConnectorProvider.java
+++ b/connectors/helidon-connector/src/main/java17/org/glassfish/jersey/helidon/connector/HelidonConnectorProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, 2025 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2025 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -23,13 +23,6 @@
 import jakarta.ws.rs.ProcessingException;
 import jakarta.ws.rs.client.Client;
 import jakarta.ws.rs.core.Configuration;
-
-import java.io.OutputStream;
-
-import org.glassfish.jersey.Beta;
-import org.glassfish.jersey.client.spi.Connector;
-import org.glassfish.jersey.client.spi.ConnectorProvider;
-import org.glassfish.jersey.internal.util.JdkVersion;
 import org.glassfish.jersey.internal.util.collection.LazyValue;
 import org.glassfish.jersey.internal.util.collection.Value;
 import org.glassfish.jersey.internal.util.collection.Values;
@@ -40,14 +33,11 @@
  *
  * @since 3.0.5
  */
-@Beta
 public class HelidonConnectorProvider implements ConnectorProvider {
+
     private static final LazyValue<Helidon3ConnectorProvider> helidon3ConnectorProvider =
             Values.lazy((Value<Helidon3ConnectorProvider>) Helidon3ConnectorProvider::new);
 
-    public HelidonConnectorProvider() {
-    }
-
     @Override
     public Connector getConnector(Client client, Configuration runtimeConfig) {
         if (HelidonVersionChecker.VERSION.get() == HelidonVersionChecker.Version.VERSION_3) {
@@ -55,6 +45,6 @@
         } else if (JdkVersion.getJdkVersion().getMajor() < 21) {
             throw new ProcessingException(LocalizationMessages.HELIDON_4_NOT_SUPPORTED());
         }
-        return new HelidonConnector(client, runtimeConfig);
+        return null;
     }
-}
+}
\ No newline at end of file
diff --git a/connectors/helidon-connector/src/main/java21/org/glassfish/jersey/helidon/connector/HelidonClientProperties.java b/connectors/helidon-connector/src/main/java21/org/glassfish/jersey/helidon/connector/HelidonClientProperties.java
index 5f47b6b..b0d8401 100644
--- a/connectors/helidon-connector/src/main/java21/org/glassfish/jersey/helidon/connector/HelidonClientProperties.java
+++ b/connectors/helidon-connector/src/main/java21/org/glassfish/jersey/helidon/connector/HelidonClientProperties.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, 2024 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2025 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -13,20 +13,78 @@
  *
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
+
 package org.glassfish.jersey.helidon.connector;
 
-import io.helidon.jersey.connector.HelidonProperties;
+import io.helidon.common.tls.Tls;
+import io.helidon.config.Config;
+import io.helidon.webclient.api.WebClient;
 import org.glassfish.jersey.internal.util.PropertiesClass;
 
+import java.util.List;
+import java.util.Map;
+
 /**
- * Configuration options specific to the Client API that utilizes {@code HelidonConnectorProvider}.
+ * Configuration options specific to the Client API that utilizes {@code HelidonConnectorProvider}
  * @since 2.31
  */
 @PropertiesClass
 public final class HelidonClientProperties {
 
+    private HelidonClientProperties() {
+    }
+
     /**
-     * A Helidon {@link Config} instance that is passed to {@link WebClient.Builder#config(Config)} if available
+     * Property name to set a {@link Config} instance to by used by underlying {@link WebClient}.
+     * This property is settable on {@link jakarta.ws.rs.core.Configurable#property(String, Object)}.
+     *
+     * @see io.helidon.webclient.api.WebClientConfig.Builder#config(io.helidon.common.config.Config)
      */
-    public static final String CONFIG = HelidonProperties.CONFIG;
+    public static final String CONFIG = "jersey.connector.helidon.config";
+
+    /**
+     * Property name to set a {@link Tls} instance to be used by underlying {@link WebClient}.
+     * This property is settable on {@link jakarta.ws.rs.core.Configurable#property(String, Object)}.
+     *
+     * @see io.helidon.webclient.api.WebClientConfig.Builder#tls(Tls)
+     */
+    public static final String TLS = "jersey.connector.helidon.tls";
+
+    /**
+     * Property name to set a {@code List<? extends  ProtocolConfig>} instance with a list of
+     * protocol configs to be used by underlying {@link WebClient}.
+     * This property is settable on {@link jakarta.ws.rs.core.Configurable#property(String, Object)}.
+     *
+     * @see io.helidon.webclient.api.WebClientConfig.Builder#protocolConfigs(List)
+     */
+    public static final String PROTOCOL_CONFIGS = "jersey.connector.helidon.protocolConfigs";
+
+    /**
+     * Property name to set a {@code Map<String, String>} instance with a list of
+     * default headers to be used by underlying {@link WebClient}.
+     * This property is settable on {@link jakarta.ws.rs.core.Configurable#property(String, Object)}.
+     *
+     * @see io.helidon.webclient.api.WebClientConfig.Builder#defaultHeadersMap(Map)
+     */
+    public static final String DEFAULT_HEADERS = "jersey.connector.helidon.defaultHeaders";
+
+    /**
+     * Property name to set a protocol ID for each request. You can use this property
+     * to request an HTTP/2 upgrade from HTTP/1.1 by setting its value to {@code "h2"}.
+     * When using TLS, Helidon uses negotiation via the ALPN extension instead of this
+     * property.
+     *
+     * @see io.helidon.webclient.api.HttpClientRequest#protocolId(String)
+     */
+    public static final String PROTOCOL_ID = "jersey.connector.helidon.protocolId";
+
+    /**
+     * Property name to enable or disable connection caching in the underlying {@link WebClient}.
+     * The default for the Helidon connector is {@code false}, or no sharing (which is the
+     * opposite of {@link WebClient}). Set this property to {@code true} to enable connection
+     * caching.
+     *
+     * @see io.helidon.webclient.api.WebClientConfig.Builder#shareConnectionCache(boolean)
+     */
+    public static final String SHARE_CONNECTION_CACHE = "jersey.connector.helidon.shareConnectionCache";
 }
diff --git a/connectors/helidon-connector/src/main/java17/org/glassfish/jersey/helidon/connector/HelidonConnector.java b/connectors/helidon-connector/src/main/java21/org/glassfish/jersey/helidon/connector/HelidonConnector.java
similarity index 100%
rename from connectors/helidon-connector/src/main/java17/org/glassfish/jersey/helidon/connector/HelidonConnector.java
rename to connectors/helidon-connector/src/main/java21/org/glassfish/jersey/helidon/connector/HelidonConnector.java
diff --git a/connectors/helidon-connector/src/main/java21/org/glassfish/jersey/helidon/connector/HelidonConnectorProvider.java b/connectors/helidon-connector/src/main/java21/org/glassfish/jersey/helidon/connector/HelidonConnectorProvider.java
index 263408d..6fc740c 100644
--- a/connectors/helidon-connector/src/main/java21/org/glassfish/jersey/helidon/connector/HelidonConnectorProvider.java
+++ b/connectors/helidon-connector/src/main/java21/org/glassfish/jersey/helidon/connector/HelidonConnectorProvider.java
@@ -16,58 +16,45 @@
 
 package org.glassfish.jersey.helidon.connector;
 
-import org.glassfish.jersey.Beta;
 import org.glassfish.jersey.client.spi.Connector;
+import org.glassfish.jersey.client.spi.ConnectorProvider;
 import org.glassfish.jersey.internal.util.JdkVersion;
 
 import jakarta.ws.rs.ProcessingException;
 import jakarta.ws.rs.client.Client;
 import jakarta.ws.rs.core.Configuration;
+
 import java.io.OutputStream;
 
+import org.glassfish.jersey.Beta;
+import org.glassfish.jersey.client.spi.Connector;
+import org.glassfish.jersey.client.spi.ConnectorProvider;
+import org.glassfish.jersey.internal.util.JdkVersion;
+import org.glassfish.jersey.internal.util.collection.LazyValue;
+import org.glassfish.jersey.internal.util.collection.Value;
+import org.glassfish.jersey.internal.util.collection.Values;
+
 /**
- * Provider for Helidon WebClient {@link Connector} that utilizes the Helidon HTTP Client to send and receive
- * HTTP request and responses. JDK 8 is not supported by the Helidon Connector.
- * <p>
- * The following properties are only supported at construction of this class:
- * <ul>
- * <li>{@link org.glassfish.jersey.client.ClientProperties#CONNECT_TIMEOUT}</li>
- * <li>{@link org.glassfish.jersey.client.ClientProperties#FOLLOW_REDIRECTS}</li>
- * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_URI}</li>
- * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_USERNAME}</li>
- * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_PASSWORD}</li>
- * <li>{@link org.glassfish.jersey.client.ClientProperties#READ_TIMEOUT}</li>
- * <li>{@link HelidonClientProperties#CONFIG}</li>
- * </ul>
- * <p>
- * If a {@link org.glassfish.jersey.client.ClientResponse} is obtained and an
- * entity is not read from the response then
- * {@link org.glassfish.jersey.client.ClientResponse#close()} MUST be called
- * after processing the response to release connection-based resources.
- * </p>
- * <p>
- * Client operations are thread safe, the HTTP connection may
- * be shared between different threads.
- * </p>
- * <p>
- * If a response entity is obtained that is an instance of {@link java.io.Closeable}
- * then the instance MUST be closed after processing the entity to release
- * connection-based resources.
- * </p>
- * <p>
- * This connector uses {@link org.glassfish.jersey.client.ClientProperties#OUTBOUND_CONTENT_LENGTH_BUFFER} to buffer the entity
- * written for instance by {@link jakarta.ws.rs.core.StreamingOutput}. Should the buffer be small and
- * {@link jakarta.ws.rs.core.StreamingOutput#write(OutputStream)} be called many times, the performance can drop. The Content-Length
- * or the Content_Encoding header is set by the underlaying Helidon WebClient regardless of the
- * {@link org.glassfish.jersey.client.ClientProperties#OUTBOUND_CONTENT_LENGTH_BUFFER} size, however.
- * </p>
+ * Helidon Connector stub which only throws exception when running on JDK prior to 21.
+ * New Helidon 3 does not support JDKs prior to 21.
  *
- * @since 2.31
+ * @since 3.0.5
  */
 @Beta
-public class HelidonConnectorProvider extends io.helidon.jersey.connector.HelidonConnectorProvider {
+public class HelidonConnectorProvider implements ConnectorProvider {
+    private static final LazyValue<Helidon3ConnectorProvider> helidon3ConnectorProvider =
+            Values.lazy((Value<Helidon3ConnectorProvider>) Helidon3ConnectorProvider::new);
+
+    public HelidonConnectorProvider() {
+    }
+
     @Override
     public Connector getConnector(Client client, Configuration runtimeConfig) {
-        return super.getConnector(client, runtimeConfig);
+        if (HelidonVersionChecker.VERSION.get() == HelidonVersionChecker.Version.VERSION_3) {
+            return helidon3ConnectorProvider.get().getConnector(client, runtimeConfig);
+        } else if (JdkVersion.getJdkVersion().getMajor() < 21) {
+            throw new ProcessingException(LocalizationMessages.HELIDON_4_NOT_SUPPORTED());
+        }
+        return new HelidonConnector(client, runtimeConfig);
     }
 }
diff --git a/connectors/helidon-connector/src/main/java17/org/glassfish/jersey/helidon/connector/ProxyBuilder.java b/connectors/helidon-connector/src/main/java21/org/glassfish/jersey/helidon/connector/ProxyBuilder.java
similarity index 100%
rename from connectors/helidon-connector/src/main/java17/org/glassfish/jersey/helidon/connector/ProxyBuilder.java
rename to connectors/helidon-connector/src/main/java21/org/glassfish/jersey/helidon/connector/ProxyBuilder.java
diff --git a/connectors/helidon-connector/src/main/resources/org/glassfish/jersey/helidon/connector/localization.properties b/connectors/helidon-connector/src/main/resources/org/glassfish/jersey/helidon/connector/localization.properties
index f4e68d2..c92aa1d 100644
--- a/connectors/helidon-connector/src/main/resources/org/glassfish/jersey/helidon/connector/localization.properties
+++ b/connectors/helidon-connector/src/main/resources/org/glassfish/jersey/helidon/connector/localization.properties
@@ -19,4 +19,5 @@
 helidon4.not.supported=Helidon 4 connector is not supported on JDK version less than 21.
 no.config.in.registery=Unable to find Config in service registry.
 proxy.schema.not.supported=Proxy schema {0} not supported.
-wrong.proxy.uri.type=The proxy URI "{0}" MUST be String or URI.
\ No newline at end of file
+wrong.proxy.uri.type=The proxy URI "{0}" MUST be String or URI.
+not.supported=Helidon connector is not supported on JDK version less than 21.
\ No newline at end of file