WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Conversation

@manuelsblanco
Copy link
Contributor

@manuelsblanco manuelsblanco commented Dec 22, 2025

User description

This change prevents compilation errors in HttpClient implementations that do not support
native Java HTTP operations by providing default implementations for the newly added methods.

🔗 Related Issues

Fixes #16673

💥 What does this PR do?

This PR makes the newly introduced native HTTP client methods (sendNative and
sendAsyncNative) optional by providing default implementations in the
HttpClient interface.

The default implementations throw UnsupportedOperationException, preserving the
previous behavior for clients that do not support Java 11 native HTTP APIs, while
allowing implementations such as JdkHttpClient to override and provide full
support.

🔧 Implementation Notes

  • The methods are implemented as default in the HttpClient interface to avoid
    breaking existing implementations.
  • Redundant overrides that only threw UnsupportedOperationException were removed
    from internal and test HTTP client implementations.
  • Implementations that support native HTTP operations (e.g. JdkHttpClient) remain
    unchanged and continue to provide concrete behavior.

Alternative approaches considered:

  • Making the methods abstract (rejected due to breaking existing implementations).
  • Introducing a separate sub-interface for native HTTP support (rejected due to
    added complexity and limited benefit).

💡 Additional Considerations

  • Existing behavior is preserved for all current HttpClient implementations.
  • No functional changes for users unless they explicitly rely on the new native
    HTTP methods.
  • Unit tests continue to validate both supported and unsupported implementations.

🔄 Types of changes

  • Bug fix (backwards compatible)

PR Type

Bug fix


Description

  • Adds default implementations for native HTTP methods in HttpClient interface

  • Removes redundant method overrides from multiple implementations

  • Methods now throw UnsupportedOperationException by default

  • Allows implementations to optionally override native HTTP support


Diagram Walkthrough

flowchart LR
  A["HttpClient Interface"] -->|"adds default implementations"| B["sendAsyncNative()"]
  A -->|"adds default implementations"| C["sendNative()"]
  B -->|"throws UnsupportedOperationException"| D["Default Behavior"]
  C -->|"throws UnsupportedOperationException"| D
  E["Implementation Classes"] -->|"remove redundant overrides"| F["RoutableHttpClientFactory"]
  E -->|"remove redundant overrides"| G["RemoteWebDriverBuilder"]
  E -->|"remove redundant overrides"| H["PassthroughHttpClient"]
  E -->|"remove redundant overrides"| I["ProtocolHandshakeTest"]
Loading

File Walkthrough

Relevant files
Bug fix
HttpClient.java
Add default implementations for native HTTP methods           

java/src/org/openqa/selenium/remote/http/HttpClient.java

  • Converts sendAsyncNative() from abstract to default method with
    UnsupportedOperationException
  • Converts sendNative() from abstract to default method with
    UnsupportedOperationException
  • Provides default implementations that preserve backward compatibility
  • Allows subclasses to optionally override with actual implementations
+11/-6   
Cleanup
RoutableHttpClientFactory.java
Remove redundant native HTTP method overrides                       

java/src/org/openqa/selenium/grid/web/RoutableHttpClientFactory.java

  • Removes redundant sendAsyncNative() override that only threw exception
  • Removes redundant sendNative() override that only threw exception
  • Relies on default implementations from HttpClient interface
+0/-15   
RemoteWebDriverBuilder.java
Remove redundant native HTTP method overrides                       

java/src/org/openqa/selenium/remote/RemoteWebDriverBuilder.java

  • Removes redundant sendAsyncNative() override that only threw exception
  • Removes redundant sendNative() override that only threw exception
  • Relies on default implementations from HttpClient interface
+0/-17   
PassthroughHttpClient.java
Remove redundant native HTTP method overrides                       

java/test/org/openqa/selenium/grid/testing/PassthroughHttpClient.java

  • Removes redundant sendAsyncNative() override that only threw exception
  • Removes redundant sendNative() override that only threw exception
  • Relies on default implementations from HttpClient interface
+0/-13   
ProtocolHandshakeTest.java
Remove redundant native HTTP method overrides                       

java/test/org/openqa/selenium/remote/ProtocolHandshakeTest.java

  • Removes redundant sendAsyncNative() override that only threw exception
  • Removes redundant sendNative() override that only threw exception
  • Relies on default implementations from HttpClient interface
+0/-14   
Formatting
NativeHttpClientMethodsTest.java
Minor formatting adjustments                                                         

java/test/org/openqa/selenium/remote/http/NativeHttpClientMethodsTest.java

  • Adds whitespace formatting between method implementations
  • No functional changes to test logic
+2/-0     

This prevents compilation errors in HttpClient implementations that do not
support native Java HTTP operations.

Fixes SeleniumHQ#16673
@selenium-ci selenium-ci added B-grid Everything grid and server related C-java Java Bindings labels Dec 22, 2025
@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Dec 22, 2025

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Dec 22, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Return failed future in async method

In the default implementation of sendAsyncNative, return a
CompletableFuture.failedFuture instead of throwing UnsupportedOperationException
directly. This aligns with the expected behavior of asynchronous methods.

java/src/org/openqa/selenium/remote/http/HttpClient.java [50-54]

 default <T> CompletableFuture<java.net.http.HttpResponse<T>> sendAsyncNative(
   java.net.http.HttpRequest request,
   java.net.http.HttpResponse.BodyHandler<T> handler) {
-  throw new UnsupportedOperationException("sendAsyncNative is not supported by this HttpClient implementation");
+  return CompletableFuture.failedFuture(
+    new UnsupportedOperationException("sendAsyncNative is not supported by this HttpClient implementation"));
 }
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: This suggestion corrects a violation of the asynchronous method contract. Throwing an exception directly from an async method is incorrect; it should return a future that completes exceptionally, which this change implements.

Medium
General
Implement synchronous method using async version

Implement the default sendNative method by calling the asynchronous
sendAsyncNative method and blocking for its result. This provides a synchronous
implementation for free to classes that implement the async version.

java/src/org/openqa/selenium/remote/http/HttpClient.java [66-71]

 default <T> java.net.http.HttpResponse<T> sendNative(
   java.net.http.HttpRequest request,
   java.net.http.HttpResponse.BodyHandler<T> handler)
   throws java.io.IOException, InterruptedException {
-  throw new UnsupportedOperationException("sendNative is not supported by this HttpClient implementation");
+  try {
+    return sendAsyncNative(request, handler).get();
+  } catch (java.util.concurrent.ExecutionException e) {
+    Throwable cause = e.getCause();
+    if (cause instanceof java.io.IOException) {
+      throw (java.io.IOException) cause;
+    }
+    if (cause instanceof RuntimeException) {
+      throw (RuntimeException) cause;
+    }
+    if (cause instanceof Error) {
+      throw (Error) cause;
+    }
+    throw new RuntimeException(cause);
+  }
 }
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: This is a valuable design improvement that provides a more useful default implementation for sendNative by leveraging sendAsyncNative, enhancing code reuse and making the interface easier to implement.

Medium
  • Update

@cgoldberg cgoldberg changed the title fix(java): provide default implementations for native HttpClient methods [java] Provide default implementations for native HttpClient methods Dec 22, 2025
Copy link
Member

@diemol diemol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please run the script formatter, at ./scripts/format.sh.

@joerg1985, can you please review as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

B-grid Everything grid and server related C-java Java Bindings Review effort 2/5

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[🐛 Bug]: Breaking change in #16412 to the HttpClient interface

4 participants