Skip to content

[java] specify nullability in package org.openqa.selenium.remote#17325

Open
asolntsev wants to merge 1 commit intoSeleniumHQ:trunkfrom
asolntsev:nullability
Open

[java] specify nullability in package org.openqa.selenium.remote#17325
asolntsev wants to merge 1 commit intoSeleniumHQ:trunkfrom
asolntsev:nullability

Conversation

@asolntsev
Copy link
Copy Markdown
Contributor

@asolntsev asolntsev commented Apr 9, 2026

  • Mark everything as non-nullable by default, and
  • Mark only the needed methods/parameters as nullable.

🔗 Related Issues

Partially implements #14291

🔄 Types of changes

  • Cleanup (formatting, renaming)
  • Breaking change (heoretically, it can break backward compatibility for Kotlin projects)

@selenium-ci selenium-ci added B-grid Everything grid and server related C-java Java Bindings B-build Includes scripting, bazel and CI integrations B-devtools Includes everything BiDi or Chrome DevTools related B-support Issue or PR related to support classes labels Apr 9, 2026
@selenium-ci
Copy link
Copy Markdown
Member

Thank you, @asolntsev for this code suggestion.

The support packages contain example code that many users find helpful, but they do not necessarily represent
the best practices for using Selenium, and the Selenium team is not currently merging changes to them.

After reviewing the change, unless it is a critical fix or a feature that is needed for Selenium
to work, we will likely close the PR.

We actively encourage people to add the wrapper and helper code that makes sense for them to their own frameworks.
If you have any questions, please contact us

@qodo-code-review
Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Specify nullability in Java bindings using JSpecify annotations

✨ Enhancement 🧪 Tests

Grey Divider

Walkthroughs

Description
  Specify nullability in the Java bindings using JSpecify annotations
  * Mark everything as non-nullable by default using @NullMarked at package level across multiple
  packages
  * Add selective @Nullable annotations to specific fields, parameters, and return types that can be
  null
  * Replace manual null checks with utility methods like Require.nonNull() and
  requireNonNullElse()
  * Make DriverService abstract and refine nullability of its fields and methods
  * Extract PasswordAuthenticator class from JdkHttpClient for better code organization
  * Add query parameter utility methods to HttpRequest (getQueryString(),
  forEachQueryParameter(), getQueryParameters())
  * Add new getHeader() method to HttpMessage with default value support
  * Make inner classes final where appropriate (e.g., in Route, UrlTemplate)
  * Update driver service implementations (Chrome, Firefox, Safari, Edge, IE) to make
  timeout parameter non-nullable
  * Add comprehensive test coverage for new functionality (PasswordAuthenticatorTest,
  HttpRequestTest)
  * Update multiple test classes with nullability annotations and improve test robustness
  * Add package-info.java files with @NullMarked annotation to 16 packages
  * Update BUILD.bazel files to include org.jspecify:jspecify dependency
  * Minor code cleanups and refactorings to improve null-safety analysis
  Partially implements #14291

Grey Divider

File Changes

1. java/src/org/openqa/selenium/remote/RemoteWebDriver.java ✨ Enhancement +26/-36

Specify nullability in RemoteWebDriver with selective annotations

• Removed @NullMarked and @NonNull annotations, replaced with selective @Nullable on specific
 fields and methods
• Initialized previously uninitialized fields (converter, remoteLogs) at declaration time
• Added @Nullable annotations to sessionId, remoteScript, remoteNetwork, and return types of
 getSessionId(), executeAsyncScript(), execute(), getFederatedCredentialManagementDialog()
• Replaced manual null checks with Require.nonNull() and requireNonNull() utility methods
• Removed @NullMarked from method implementations like perform(), addVirtualAuthenticator(),
 removeVirtualAuthenticator()

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


2. java/test/org/openqa/selenium/remote/ProtocolHandshakeTest.java 🧪 Tests +27/-27

Refactor ProtocolHandshakeTest with nullability annotations

• Added @NullMarked and @Nullable annotations to test class and methods
• Extracted repeated HTTP response setup into createClient() helper method
• Changed RecordingHttpClient from inner class to private static class
• Updated assertion from assertThatExceptionOfType() to assertThatThrownBy() with message
 validation
• Replaced string() method call with request.contentAsString()

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


3. java/test/org/openqa/selenium/grid/router/TunnelWebsocketTest.java 🧪 Tests +14/-10

Add nullability annotations to TunnelWebsocketTest

• Added @Nullable type parameters to AtomicReference declarations throughout test methods
• Added @NullMarked annotations to specific test methods
• Updated method signatures to use parameterized AtomicReference<@Nullable String> and
 AtomicReference<@Nullable URL>

java/test/org/openqa/selenium/grid/router/TunnelWebsocketTest.java


View more (136)
4. java/src/org/openqa/selenium/remote/ErrorHandler.java ✨ Enhancement +10/-5

Add nullability annotations to ErrorHandler methods

• Added @Nullable annotation to UNKNOWN_FILE constant
• Added @Nullable return type annotations to createUnhandledAlertException() and
 rebuildServerError() methods
• Fixed null-safety check by using UnhandledAlertException.class.equals(clazz) instead of
 clazz.equals()
• Added null check before calling Throwable.class.isAssignableFrom(clazz)
• Added @Nullable annotations to FrameInfoToStackFrame.apply() parameter and toStringOrNull()
 method

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


5. java/src/org/openqa/selenium/remote/AbstractDriverOptions.java ✨ Enhancement +9/-8

Refactor AbstractDriverOptions with nullability annotations

• Removed @NonNull annotation from self() method
• Added @Nullable return type annotation to getCapability() method
• Updated asMap() to use requireNonNull() on capability values
• Replaced Collections.unmodifiableMap() calls with static import unmodifiableMap()

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


6. java/src/org/openqa/selenium/remote/codec/AbstractHttpResponseCodec.java ✨ Enhancement +14/-13

Simplify AbstractHttpResponseCodec with utility methods

• Replaced Objects.requireNonNullElse() with static import requireNonNullElse()
• Removed string() method call, replaced with contentAsString()
• Simplified header retrieval using new getHeader(HttpHeader, String) method
• Extracted response status and state to local variables for better null-safety analysis

java/src/org/openqa/selenium/remote/codec/AbstractHttpResponseCodec.java


7. java/src/org/openqa/selenium/remote/RemoteWebElement.java ✨ Enhancement +8/-6

Add nullability annotations to RemoteWebElement

• Added @Nullable annotation to foundBy field and getId() return type
• Replaced manual null checks with Require.nonNull() calls in sendKeys() method
• Added @Nullable type parameter to List<@Nullable File> for file detection results

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


8. java/test/org/openqa/selenium/netty/server/WebSocketServingTest.java 🧪 Tests +3/-46

Add nullability annotations to WebSocketServingTest

• Added @NullMarked annotations to specific test methods
• Removed unused imports (MILLISECONDS, Executors, ScheduledExecutorService)

java/test/org/openqa/selenium/netty/server/WebSocketServingTest.java


9. java/src/org/openqa/selenium/remote/ErrorCodes.java ✨ Enhancement +5/-3

Add nullability annotations to ErrorCodes methods

• Added @Nullable annotations to method parameters: toState(), toStatusCode(),
 isMappableError()
• Added @Nullable return type annotation to getExceptionType() method

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


10. java/src/org/openqa/selenium/Platform.java ✨ Enhancement +5/-3

Add nullability annotations to Platform methods

• Added @Nullable annotations to extractFromSysProperty() method parameters
• Extracted family() call to local variable in is() method for improved null-safety

java/src/org/openqa/selenium/Platform.java


11. java/src/org/openqa/selenium/remote/http/ClientConfig.java ✨ Enhancement +20/-9

Add nullability annotations to ClientConfig

• Added @Nullable annotations to fields: baseUri, proxy, credentials, sslContext
• Added @Nullable annotations to constructor parameters and getter methods
• Refactored baseUrl() method to use Optional and extracted toURL() helper method

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


12. java/src/org/openqa/selenium/remote/service/DriverService.java ✨ Enhancement +9/-12

Make DriverService abstract with nullability refinements

• Changed class from concrete to abstract
• Added @Nullable annotation to executable field and getExecutable() return type
• Added @Nullable annotation to process field
• Changed timeout parameter from @Nullable to non-nullable in constructor
• Changed getDriverProperty() and getDriverEnvironmentVariable() to abstract methods
• Added @Nullable type parameter to CompletableFuture<@Nullable StartOrDie>
• Set default value for timeout field in Builder class

java/src/org/openqa/selenium/remote/service/DriverService.java


13. java/src/org/openqa/selenium/remote/JsonToWebElementConverter.java ✨ Enhancement +5/-2

Add nullability annotations to JsonToWebElementConverter

• Added @Nullable annotation to driver field and constructor parameter
• Added @Nullable return type annotations to getElementKey() and getShadowRootKey() methods

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


14. java/src/org/openqa/selenium/remote/http/Route.java ✨ Enhancement +10/-16

Refactor Route classes with final modifiers and utility methods

• Changed inner classes to final: TemplatizedRouteConfig, TemplatizedRoute, CombinedRoute,
 PredicatedConfig, PredicatedRoute
• Refactored query parameter iteration using forEachQueryParameter() method
• Replaced manual null check with Require.nonNull() in PredicatedRoute.handle()

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


15. java/src/org/openqa/selenium/remote/RemoteNetwork.java 🐞 Bug fix +2/-6

Clean up RemoteNetwork by removing unused field

• Removed unused biDi field and related import
• Changed inner classes AuthDetails and RequestDetails to static

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


16. java/src/org/openqa/selenium/remote/http/jdk/JdkHttpClient.java ✨ Enhancement +5/-15

Extract PasswordAuthenticator and add nullability annotations

• Added @Nullable annotation to WebSocket listener methods
• Extracted password authentication logic into new PasswordAuthenticator class

java/src/org/openqa/selenium/remote/http/jdk/JdkHttpClient.java


17. java/src/org/openqa/selenium/remote/http/HttpRequest.java ✨ Enhancement +35/-0

Add query parameter utility methods to HttpRequest

• Added @Nullable return type annotation to getQueryParameter() and getQueryParameters()
• Added new methods: forEachQueryParameter(), getQueryString(), getQueryParameters()
 (unmodifiable map)
• Added helper methods for query string encoding

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


18. java/test/org/openqa/selenium/remote/RemoteWebDriverBuilderTest.java 🧪 Tests +17/-1

Add nullability annotations to RemoteWebDriverBuilderTest

• Added @NullMarked annotations to test methods and FakeDriverService class
• Added @Nullable type parameter to AtomicReference<@Nullable URI>
• Implemented abstract methods getDriverProperty() and getDriverEnvironmentVariable() in
 FakeDriverService

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


19. java/test/org/openqa/selenium/grid/router/HandleSessionReadTimeoutTest.java 🧪 Tests +5/-5

Add nullability annotations to HandleSessionReadTimeoutTest

• Added @Nullable type parameters to AtomicReference<@Nullable Duration> declarations
• Removed throws Exception from runSingleRequest() method signature

java/test/org/openqa/selenium/grid/router/HandleSessionReadTimeoutTest.java


20. java/src/org/openqa/selenium/remote/WebElementToJsonConverter.java ✨ Enhancement +5/-3

Add nullability annotations to WebElementToJsonConverter

• Updated class to implement Function<@Nullable Object, @Nullable Object>
• Added @Nullable annotations to apply() method parameter and return type
• Added @Nullable type parameter to Map<String, @Nullable Object> in conversion logic

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


21. java/src/org/openqa/selenium/remote/http/UrlTemplate.java ✨ Enhancement +8/-8

Refactor UrlTemplate with nullability and final modifiers

• Fixed regex pattern for template matching
• Added @Nullable return type annotation to compiled function and match() methods
• Replaced manual null check with Require.nonEmpty() in constructor
• Changed Match inner class to static final

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


22. java/src/org/openqa/selenium/remote/codec/w3c/W3CHttpResponseCodec.java ✨ Enhancement +5/-3

Add nullability annotations to W3CHttpResponseCodec

• Added @Nullable annotation to Object array in logging statement
• Extracted response.getValue() to local variable for improved null-safety

java/src/org/openqa/selenium/remote/codec/w3c/W3CHttpResponseCodec.java


23. java/src/org/openqa/selenium/remote/RemoteWebDriverBuilder.java ✨ Enhancement +5/-5

Add nullability annotations to RemoteWebDriverBuilder

• Added @Nullable annotations to fields: remoteHost, driverService, credentials
• Added @Nullable return type annotation to startDriverServiceIfNecessary() method
• Removed throws clause from sendNative() method

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


24. java/src/org/openqa/selenium/json/Json.java ✨ Enhancement +3/-2

Add nullability annotations to Json.toJson methods

• Added @Nullable annotations to toJson() method parameters

java/src/org/openqa/selenium/json/Json.java


25. java/test/org/openqa/selenium/remote/http/HttpRequestTest.java 🧪 Tests +43/-0

Add tests for HttpRequest query string methods

• New test file for HttpRequest query string functionality
• Tests getQueryString() method with multiple and single parameters

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


26. java/src/org/openqa/selenium/remote/UnreachableBrowserException.java ✨ Enhancement +2/-5

Remove nullability annotations from UnreachableBrowserException

• Removed @NullMarked and @Nullable annotations from class and constructor parameters
• Changed constructor parameters from @Nullable to non-nullable

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


27. java/test/org/openqa/selenium/remote/http/jdk/PasswordAuthenticatorTest.java 🧪 Tests +41/-0

Add tests for PasswordAuthenticator

• New test file for PasswordAuthenticator class
• Tests username/password parsing and empty password handling

java/test/org/openqa/selenium/remote/http/jdk/PasswordAuthenticatorTest.java


28. java/src/org/openqa/selenium/remote/Command.java ✨ Enhancement +6/-3

Add nullability annotations to Command class

• Added @Nullable annotations to sessionId field and constructor parameters
• Added @Nullable return type annotation to getSessionId() method
• Added //noinspection DataFlowIssue comment in fromJson() method

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


29. java/src/org/openqa/selenium/remote/http/jdk/JdkHttpMessages.java ✨ Enhancement +1/-17

Simplify query string building in JdkHttpMessages

• Simplified query string building by using req.getQueryString() method
• Removed manual query parameter iteration and encoding logic

java/src/org/openqa/selenium/remote/http/jdk/JdkHttpMessages.java


30. java/src/org/openqa/selenium/remote/W3CHandshakeResponse.java ✨ Enhancement +3/-2

Add nullability annotations to W3CHandshakeResponse

• Added @Nullable return type annotations to errorHandler() and successHandler() methods

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


31. java/src/org/openqa/selenium/remote/http/jdk/PasswordAuthenticator.java ✨ Enhancement +37/-0

Extract PasswordAuthenticator class for reusability

• New class extracted from JdkHttpClient for password authentication
• Handles parsing of userinfo string and provides PasswordAuthentication

java/src/org/openqa/selenium/remote/http/jdk/PasswordAuthenticator.java


32. java/test/org/openqa/selenium/remote/http/HttpClientFactoryTest.java 🧪 Tests +7/-3

Add nullability annotations to HttpClientFactoryTest

• Added @NullMarked annotations to factory test classes
• Changed factory implementations to throw UnsupportedOperationException instead of returning null

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


33. java/test/org/openqa/selenium/remote/AugmenterTest.java 🧪 Tests +6/-1

Add nullability annotations to AugmenterTest

• Added @NullMarked annotations to test class and inner classes
• Changed findElement() to throw exception instead of returning null

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


34. java/src/org/openqa/selenium/remote/tracing/opentelemetry/OpenTelemetryPropagator.java ✨ Enhancement +5/-3

Add nullability annotations to OpenTelemetryPropagator

• Added @Nullable annotations to BiFunction type parameters
• Updated anonymous TextMapGetter implementation with @Nullable return type

java/src/org/openqa/selenium/remote/tracing/opentelemetry/OpenTelemetryPropagator.java


35. java/test/org/openqa/selenium/environment/webserver/NettyAppServer.java ✨ Enhancement +7/-3

Add nullability annotations to NettyAppServer

• Added @Nullable annotations to server and secure fields
• Added null check in stop() method before calling server.stop()
• Added @Nullable return type annotation to getAlternateHostName() method

java/test/org/openqa/selenium/environment/webserver/NettyAppServer.java


36. java/src/org/openqa/selenium/remote/ScreenshotException.java ✨ Enhancement +3/-5

Remove nullability annotations from ScreenshotException

• Removed @NullMarked annotation from class
• Changed constructor parameters from @Nullable to non-nullable (except cause in one constructor)

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


37. java/src/org/openqa/selenium/remote/HttpCommandExecutor.java ✨ Enhancement +3/-2

Add nullability annotations to HttpCommandExecutor

• Added @Nullable annotations to commandCodec and responseCodec fields

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


38. java/src/org/openqa/selenium/remote/tracing/opentelemetry/OpenTelemetryTracer.java ✨ Enhancement +3/-2

Add nullability annotations to OpenTelemetryTracer

• Added @Nullable annotation to singleton static field
• Added @Nullable annotation to context field

java/src/org/openqa/selenium/remote/tracing/opentelemetry/OpenTelemetryTracer.java


39. java/src/org/openqa/selenium/remote/HandshakeResponse.java ✨ Enhancement +5/-3

Add nullability annotations to HandshakeResponse interface

• Added @Nullable return type annotations to errorHandler(), successHandler(), and
 getResponseFunction() methods

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


40. java/src/org/openqa/selenium/remote/CommandPayload.java ✨ Enhancement +3/-4

Add validation to CommandPayload constructor

• Removed @NullMarked annotation from class
• Added Require.nonNull() validation in constructor for name and parameters

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


41. java/src/org/openqa/selenium/remote/http/AddSeleniumUserAgent.java ✨ Enhancement +9/-7

Refactor AddSeleniumUserAgent with helper method

• Extracted platform label computation into platformLabel() helper method
• Used requireNonNullElse() to handle null platform family
• Simplified USER_AGENT constant initialization

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


42. java/src/org/openqa/selenium/remote/ProtocolHandshake.java ✨ Enhancement +2/-1

Add nullability annotation to ProtocolHandshake

• Added @Nullable return type annotation to massageProxy function

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


43. java/test/org/openqa/selenium/testing/drivers/OutOfProcessSeleniumServer.java ✨ Enhancement +4/-3

Add nullability annotations to OutOfProcessSeleniumServer

• Added @Nullable annotations to baseUrl and process fields with null initialization
• Changed filter predicate from Objects::nonNull to prop -> !prop.isEmpty()

java/test/org/openqa/selenium/testing/drivers/OutOfProcessSeleniumServer.java


44. java/src/org/openqa/selenium/devtools/Connection.java ✨ Enhancement +2/-0

Add nullability annotation to Connection.Listener

• Added @NullMarked annotation to inner Listener class

java/src/org/openqa/selenium/devtools/Connection.java


45. java/test/org/openqa/selenium/support/pagefactory/AnnotationsTest.java 🧪 Tests +5/-2

Add nullability annotations to AnnotationsTest

• Added @NullMarked annotation to FindByXXXXBuilder inner class
• Changed findElements() to return emptyList() instead of null

java/test/org/openqa/selenium/support/pagefactory/AnnotationsTest.java


46. java/src/org/openqa/selenium/ie/InternetExplorerDriverService.java ✨ Enhancement +2/-2

Make timeout parameter non-nullable in InternetExplorerDriverService

• Changed timeout parameter from @Nullable to non-nullable in constructor and builder method

java/src/org/openqa/selenium/ie/InternetExplorerDriverService.java


47. java/src/org/openqa/selenium/remote/tracing/opentelemetry/package-info.java ✨ Enhancement +21/-0

Add package-level nullability annotation

• New package-info file with @NullMarked annotation for the package

java/src/org/openqa/selenium/remote/tracing/opentelemetry/package-info.java


48. java/src/org/openqa/selenium/chrome/ChromeDriverService.java ✨ Enhancement +2/-2

Make timeout parameter non-nullable in ChromeDriverService

• Changed timeout parameter from @Nullable to non-nullable in constructor and builder method

java/src/org/openqa/selenium/chrome/ChromeDriverService.java


49. java/src/org/openqa/selenium/edge/EdgeDriverService.java ✨ Enhancement +2/-2

Make timeout parameter non-nullable in EdgeDriverService

• Changed timeout parameter from @Nullable to non-nullable in constructor and builder method

java/src/org/openqa/selenium/edge/EdgeDriverService.java


50. java/src/org/openqa/selenium/remote/codec/w3c/package-info.java ✨ Enhancement +21/-0

Add package-level nullability annotation

• New package-info file with @NullMarked annotation for the package

java/src/org/openqa/selenium/remote/codec/w3c/package-info.java


51. java/src/org/openqa/selenium/remote/tracing/empty/package-info.java ✨ Enhancement +21/-0

Add package-level nullability annotation

• New package-info file with @NullMarked annotation for the package

java/src/org/openqa/selenium/remote/tracing/empty/package-info.java


52. java/src/org/openqa/selenium/remote/http/jdk/package-info.java ✨ Enhancement +21/-0

Add package-level nullability annotation

• New package-info file with @NullMarked annotation for the package

java/src/org/openqa/selenium/remote/http/jdk/package-info.java


53. java/src/org/openqa/selenium/remote/service/DriverFinder.java ✨ Enhancement +3/-1

Add nullability annotations to DriverFinder

• Added @Nullable annotation to result field
• Added @Nullable return type annotation to getBrowserBinary() method

java/src/org/openqa/selenium/remote/service/DriverFinder.java


54. java/src/org/openqa/selenium/remote/locators/package-info.java ✨ Enhancement +21/-0

Add package-level nullability annotation

• New package-info file with @NullMarked annotation for the package

java/src/org/openqa/selenium/remote/locators/package-info.java


55. java/src/org/openqa/selenium/support/pagefactory/internal/package-info.java ✨ Enhancement +21/-0

Add package-level nullability annotation

• New package-info file with @NullMarked annotation for the package

java/src/org/openqa/selenium/support/pagefactory/internal/package-info.java


56. java/src/org/openqa/selenium/remote/tracing/package-info.java ✨ Enhancement +21/-0

Add package-level nullability annotation

• New package-info file with @NullMarked annotation for the package

java/src/org/openqa/selenium/remote/tracing/package-info.java


57. java/src/org/openqa/selenium/support/locators/package-info.java ✨ Enhancement +21/-0

Add package-level nullability annotation

• New package-info file with @NullMarked annotation for the package

java/src/org/openqa/selenium/support/locators/package-info.java


58. java/src/org/openqa/selenium/remote/codec/package-info.java ✨ Enhancement +21/-0

Add package-level nullability annotation

• New package-info file with @NullMarked annotation for the package

java/src/org/openqa/selenium/remote/codec/package-info.java


59. java/src/org/openqa/selenium/support/decorators/package-info.java ✨ Enhancement +21/-0

Add package-level nullability annotation

• New package-info file with @NullMarked annotation for the package

java/src/org/openqa/selenium/support/decorators/package-info.java


60. java/src/org/openqa/selenium/support/pagefactory/package-info.java ✨ Enhancement +21/-0

Add package-level nullability annotation

• New package-info file with @NullMarked annotation for the package

java/src/org/openqa/selenium/support/pagefactory/package-info.java


61. java/test/org/openqa/selenium/environment/webserver/package-info.java ✨ Enhancement +21/-0

Add package-level nullability annotation

• New package-info file with @NullMarked annotation for the package

java/test/org/openqa/selenium/environment/webserver/package-info.java


62. java/src/org/openqa/selenium/remote/http/package-info.java ✨ Enhancement +21/-0

Add package-level nullability annotation

• New package-info file with @NullMarked annotation for the package

java/src/org/openqa/selenium/remote/http/package-info.java


63. java/src/org/openqa/selenium/remote/service/package-info.java ✨ Enhancement +21/-0

Add package-level nullability annotation

• New package-info file with @NullMarked annotation for the package

java/src/org/openqa/selenium/remote/service/package-info.java


64. java/src/org/openqa/selenium/support/events/package-info.java ✨ Enhancement +21/-0

Add package-level nullability annotation

• New package-info file with @NullMarked annotation for the package

java/src/org/openqa/selenium/support/events/package-info.java


65. java/test/org/openqa/selenium/grid/testing/package-info.java ✨ Enhancement +21/-0

Add package-level nullability annotation

• New package-info file with @NullMarked annotation for the package

java/test/org/openqa/selenium/grid/testing/package-info.java


66. java/src/org/openqa/selenium/remote/package-info.java ✨ Enhancement +21/-0

Add package-level nullability annotation

• New package-info file with @NullMarked annotation for the package

java/src/org/openqa/selenium/remote/package-info.java


67. java/test/org/openqa/selenium/environment/webserver/CookieHandler.java ✨ Enhancement +4/-2

Add nullability annotations to CookieHandler

• Added @Nullable annotations to method parameters in append() and escapeCookieValue() methods

java/test/org/openqa/selenium/environment/webserver/CookieHandler.java


68. java/src/org/openqa/selenium/support/package-info.java ✨ Enhancement +21/-0

Add package-level nullability annotation

• New package-info file with @NullMarked annotation for the package

java/src/org/openqa/selenium/support/package-info.java


69. java/test/org/openqa/selenium/environment/package-info.java ✨ Enhancement +21/-0

Add package-level nullability annotation

• New package-info file with @NullMarked annotation for the package

java/test/org/openqa/selenium/environment/package-info.java


70. java/src/org/openqa/selenium/grid/web/ReverseProxyHandler.java ✨ Enhancement +4/-5

Simplify query parameter handling in ReverseProxyHandler

• Refactored query parameter iteration using forEachQueryParameter() method

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


71. java/src/org/openqa/selenium/remote/http/HttpMessage.java ✨ Enhancement +6/-0

Add nullability and header utility methods to HttpMessage

• Added @Nullable return type annotation to getAttribute() method
• Added new getHeader(HttpHeader, String) method with default value support

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


72. java/test/org/openqa/selenium/environment/webserver/AppServerTestBase.java 🧪 Tests +6/-2

Add nullability annotations to AppServerTestBase

• Added @Nullable annotation to driver static field with null initialization
• Added null check in quitDriver() method before calling driver.quit()

java/test/org/openqa/selenium/environment/webserver/AppServerTestBase.java


73. java/test/org/openqa/selenium/remote/internal/WebSocketTestBase.java 🧪 Tests +3/-0

Add nullability annotations to WebSocketTestBase

• Added @NullMarked annotations to WebSocket listener methods

java/test/org/openqa/selenium/remote/internal/WebSocketTestBase.java


74. java/src/org/openqa/selenium/remote/service/DriverCommandExecutor.java ✨ Enhancement +3/-2

Add nullability annotations to DriverCommandExecutor

• Added @Nullable type parameters to CompletableFuture<@Nullable Response> declarations

java/src/org/openqa/selenium/remote/service/DriverCommandExecutor.java


75. java/src/org/openqa/selenium/remote/DesiredCapabilities.java ✨ Enhancement +1/-1

Make merge parameter non-nullable in DesiredCapabilities

• Changed merge() method parameter from @Nullable Capabilities to non-nullable Capabilities

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


76. java/test/org/openqa/selenium/support/events/EventFiringDecoratorTest.java 🧪 Tests +3/-0

Add nullability annotations to EventFiringDecoratorTest

• Added @NullMarked annotations to test class and test methods

java/test/org/openqa/selenium/support/events/EventFiringDecoratorTest.java


77. java/test/org/openqa/selenium/environment/GlobalTestEnvironment.java ✨ Enhancement +5/-2

Add nullability annotations to GlobalTestEnvironment

• Added @Nullable annotation to environment static field with null initialization
• Added requireNonNull() check in get() method with error message

java/test/org/openqa/selenium/environment/GlobalTestEnvironment.java


78. java/test/org/openqa/selenium/remote/internal/HttpClientTestBase.java ✨ Enhancement +1/-6

Simplify query parameter handling in HttpClientTestBase

• Simplified query parameter response building using req.getQueryParameters() method
• Removed manual TreeMap construction and iteration

java/test/org/openqa/selenium/remote/internal/HttpClientTestBase.java


79. java/src/org/openqa/selenium/firefox/FirefoxDriverService.java ✨ Enhancement +1/-1

Make timeout parameter non-nullable in FirefoxDriverService

• Changed timeout parameter from @Nullable to non-nullable in constructor

java/src/org/openqa/selenium/firefox/FirefoxDriverService.java


80. java/test/org/openqa/selenium/environment/webserver/AppServer.java ✨ Enhancement +3/-1

Add nullability annotations to AppServer interface

• Added @Nullable return type annotation to getAlternateHostName() method
• Added @Nullable return type annotation to detectAlternateHostname() static method

java/test/org/openqa/selenium/environment/webserver/AppServer.java


81. java/src/org/openqa/selenium/remote/tracing/empty/NullPropagator.java ✨ Enhancement +2/-1

Add nullability annotation to NullPropagator

• Added @Nullable return type annotation to BiFunction in extractContext() method

java/src/org/openqa/selenium/remote/tracing/empty/NullPropagator.java


82. java/src/org/openqa/selenium/support/events/EventFiringDecorator.java ✨ Enhancement +2/-0

Add nullability annotation to EventFiringDecorator

• Added @Nullable return type annotation to findMatchingMethod() method

java/src/org/openqa/selenium/support/events/EventFiringDecorator.java


83. java/src/org/openqa/selenium/remote/http/Contents.java ✨ Enhancement +2/-1

Add null safety to Contents.fromJson method

• Added requireNonNull() check in fromJson() method to ensure non-null result

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


84. java/test/org/openqa/selenium/grid/distributor/local/LocalDistributorTest.java 🧪 Tests +2/-1

Add nullability annotation to LocalDistributorTest

• Added @Nullable type parameter to List<Callable<@Nullable SessionId>>

java/test/org/openqa/selenium/grid/distributor/local/LocalDistributorTest.java


85. java/test/org/openqa/selenium/environment/webserver/SleepingHandler.java ✨ Enhancement +3/-1

Add null safety to SleepingHandler query parameter

• Added requireNonNull() check for required query parameter time

java/test/org/openqa/selenium/environment/webserver/SleepingHandler.java


86. java/src/org/openqa/selenium/remote/tracing/HttpTracing.java ✨ Enhancement +2/-1

Add nullability annotation to HttpTracing

• Added @Nullable annotation to context parameter in inject() method

java/src/org/openqa/selenium/remote/tracing/HttpTracing.java


87. java/src/org/openqa/selenium/support/locators/RelativeLocator.java ✨ Enhancement +2/-1

Add null safety to RelativeLocator.findElements

• Added requireNonNull() check on executeScript() result in findElements() method

java/src/org/openqa/selenium/support/locators/RelativeLocator.java


88. java/src/org/openqa/selenium/safari/SafariDriverService.java ✨ Enhancement +2/-2

Make timeout parameter non-nullable in SafariDriverService

• Changed timeout parameter from @Nullable to non-nullable in constructor and builder method

java/src/org/openqa/selenium/safari/SafariDriverService.java


89. java/src/org/openqa/selenium/remote/tracing/Propagator.java ✨ Enhancement +2/-1

Add nullability annotation to Propagator interface

• Added @Nullable return type annotation to BiFunction in extractContext() method

java/src/org/openqa/selenium/remote/tracing/Propagator.java


90. java/test/org/openqa/selenium/remote/http/NativeHttpClientMethodsTest.java 🧪 Tests +2/-0

Add nullability annotation to NativeHttpClientMethodsTest

• Added @NullMarked annotation to TestHttpClient class

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


91. java/src/org/openqa/selenium/remote/http/ConnectionFailedException.java ✨ Enhancement +2/-5

Remove nullability annotations from ConnectionFailedException

• Removed @NullMarked annotation from class
• Changed constructor parameters from @Nullable to non-nullable

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


92. java/src/org/openqa/selenium/support/AbstractFindByBuilder.java ✨ Enhancement +2/-0

Add nullability annotation to AbstractFindByBuilder

• Added @Nullable return type annotation to buildByFromShortFindBy() method

java/src/org/openqa/selenium/support/AbstractFindByBuilder.java


93. java/src/org/openqa/selenium/safari/SafariDriver.java 📝 Documentation +1/-1

Fix JavaDoc typo in SafariDriver

• Fixed JavaDoc comment from SafariDriver} to SafariDriver

java/src/org/openqa/selenium/safari/SafariDriver.java


94. java/src/org/openqa/selenium/remote/http/HttpMethod.java Cleanup +2/-3

Replace manual null check with Require utility

• Replaced manual null check with Require.nonNull() utility method
• Added import for org.openqa.selenium.internal.Require
• Simplified null validation logic in getHttpMethod() method

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


95. java/test/org/openqa/selenium/ReferrerTest.java ✨ Enhancement +2/-0

Add NullMarked annotation to RecordingHandler class

• Added @NullMarked annotation to RecordingHandler inner class
• Added import for org.jspecify.annotations.NullMarked
• Marks class as non-nullable by default per nullability specification

java/test/org/openqa/selenium/ReferrerTest.java


96. java/src/org/openqa/selenium/remote/http/HttpResponse.java ✨ Enhancement +3/-0

Mark getTargetHost method as nullable

• Added @Nullable annotation to getTargetHost() method return type
• Added import for org.jspecify.annotations.Nullable
• Explicitly marks method as potentially returning null

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


97. java/src/org/openqa/selenium/remote/http/CloseMessage.java Cleanup +3/-1

Replace null check with requireNonNullElse utility

• Replaced manual null check with requireNonNullElse() utility method
• Added import for java.util.Objects.requireNonNullElse
• Simplified null handling in CloseMessage constructor

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


98. java/test/org/openqa/selenium/remote/FakeWebDriverInfo.java ✨ Enhancement +2/-0

Add NullMarked annotation to FakeWebDriverInfo

• Added @NullMarked annotation to FakeWebDriverInfo class
• Added import for org.jspecify.annotations.NullMarked
• Marks entire class as non-nullable by default

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


</...

@qodo-code-review
Copy link
Copy Markdown
Contributor

qodo-code-review bot commented Apr 9, 2026

Code Review by Qodo

🐞 Bugs (2)   📘 Rule violations (2)   📎 Requirement gaps (0)   🎨 UX Issues (0)
🐞\ ≡ Correctness (1) ☼ Reliability (1)
📘\ ⚙ Maintainability (2)

Grey Divider


Action required

1. DriverService made abstract 📘
Description
DriverService was changed from a concrete class to an abstract class and now has new abstract
methods, which is a public API/ABI breaking change for any downstream code that instantiated it or
extended it without implementing the new abstract methods. This violates the requirement to preserve
backward compatibility or deprecate before breaking changes.
Code

java/src/org/openqa/selenium/remote/service/DriverService.java[R64-65]

+public abstract class DriverService implements Closeable {
Evidence
PR Compliance ID 1 forbids introducing breaking changes to public API/ABI without a deprecation
period. The diff changes DriverService to abstract and changes
getDriverProperty()/getDriverEnvironmentVariable() from default implementations to abstract
methods, which breaks existing subclasses and removes the ability to instantiate DriverService
directly.

AGENTS.md
java/src/org/openqa/selenium/remote/service/DriverService.java[64-65]
java/src/org/openqa/selenium/remote/service/DriverService.java[156-159]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`DriverService` was changed in a binary/source incompatible way (`class` � `abstract class`, and previously non-abstract methods now `abstract`). This can break downstream consumers at compile time and runtime.

## Issue Context
This PR is primarily about nullability. The compatibility policy requires either preserving public API/ABI or providing a deprecation/migration path before introducing breaking changes.

## Fix Focus Areas
- java/src/org/openqa/selenium/remote/service/DriverService.java[64-65]
- java/src/org/openqa/selenium/remote/service/DriverService.java[156-159]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Invalid query map return 🐞
Description
HttpRequest#getQueryParameters() declares Map<String, Iterable<String>> but returns an
unmodifiable view of a Map<String, List<String>>, which is not assignment-compatible due to
generic invariance and should not compile.
Code

java/src/org/openqa/selenium/remote/http/HttpRequest.java[R104-106]

+  public Map<String, Iterable<String>> getQueryParameters() {
+    return Collections.unmodifiableMap(queryParameters);
+  }
Evidence
The backing field is Map<String, List<String>>, but the method return type is `Map<String,
Iterable<String>>` with no wildcard/cast, so the return expression type cannot satisfy the declared
return type.

java/src/org/openqa/selenium/remote/http/HttpRequest.java[37-40]
java/src/org/openqa/selenium/remote/http/HttpRequest.java[104-106]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`HttpRequest#getQueryParameters()` returns `Collections.unmodifiableMap(queryParameters)` where `queryParameters` is `Map<String, List<String>>`, but the method signature declares `Map<String, Iterable<String>>`. This is not type-compatible in Java and should fail compilation.

### Issue Context
This method was added to support callers that want the full query-parameter multimap.

### Fix Focus Areas
- java/src/org/openqa/selenium/remote/http/HttpRequest.java[37-40]
- java/src/org/openqa/selenium/remote/http/HttpRequest.java[104-106]

### Suggested fix
Use one of:
- Change signature to `public Map<String, List<String>> getQueryParameters()` (and keep returning `Collections.unmodifiableMap(queryParameters)`), or
- Keep the abstraction but make it type-correct: `public Map<String, ? extends Iterable<String>> getQueryParameters()`.
Then update any call sites/tests accordingly.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Repo-wide nullability churn 📘
Description
The PR makes widespread, noisy changes across many packages and tests (e.g., adding
package-info.java with @NullMarked and unrelated edits), which increases review/revert risk
beyond the stated scope. This violates the preference for small, reversible diffs over broad
refactors/reformatting.
Code

java/src/org/openqa/selenium/remote/package-info.java[R1-21]

+// Licensed to the Software Freedom Conservancy (SFC) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The SFC licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+@NullMarked
+package org.openqa.selenium.remote;
+
+import org.jspecify.annotations.NullMarked;
Evidence
PR Compliance ID 2 requires narrowly scoped changes and discourages broad, noisy refactors. The diff
shows numerous cross-cutting changes outside a single tightly-scoped area, including adding multiple
package-info.java files and unrelated edits (e.g., Safari javadoc text), increasing churn not
strictly required for a focused fix.

AGENTS.md
java/src/org/openqa/selenium/remote/package-info.java[1-21]
java/src/org/openqa/selenium/support/package-info.java[1-21]
java/test/org/openqa/selenium/environment/package-info.java[1-21]
java/src/org/openqa/selenium/safari/SafariDriver.java[46-46]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
This PR introduces broad churn across many packages (multiple `package-info.java` additions and unrelated edits), reducing reviewability and increasing revert risk.

## Issue Context
Compliance requires changes to be narrowly scoped and reversible; wide refactors should be split or minimized to only what is necessary for the intended change.

## Fix Focus Areas
- java/src/org/openqa/selenium/remote/package-info.java[1-21]
- java/src/org/openqa/selenium/support/package-info.java[1-21]
- java/test/org/openqa/selenium/environment/package-info.java[1-21]
- java/src/org/openqa/selenium/safari/SafariDriver.java[46-46]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. NPE on empty JSON body 🐞
Description
Contents.fromJson now wraps JsonInput.read with requireNonNull, which throws
NullPointerException when the message body is empty/exhausted because JsonInput.read(Type)
explicitly returns null at EOF.
Code

java/src/org/openqa/selenium/remote/http/Contents.java[R169-172]

  public static <T> T fromJson(HttpMessage<?> message, Type typeOfT) {
    try (Reader reader = reader(message);
        JsonInput input = JSON.newInput(reader)) {
-      return input.read(typeOfT);
+      return requireNonNull(input.read(typeOfT));
Evidence
JsonInput.read(Type) is annotated nullable and returns null when the input is exhausted (EOF).
Contents.fromJson now unconditionally requireNonNull(...)s that value, converting an empty body
into an NPE (often reported as a 500) rather than a structured decode/validation error.

java/src/org/openqa/selenium/remote/http/Contents.java[169-175]
java/src/org/openqa/selenium/json/JsonInput.java[439-456]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`Contents.fromJson` throws a `NullPointerException` on empty request bodies because it calls `requireNonNull(input.read(typeOfT))` and `JsonInput.read` returns null on EOF.

### Issue Context
This method is used by HTTP handlers parsing request bodies (e.g., Grid endpoints). Empty bodies should ideally map to a controlled client error (e.g., `IllegalArgumentException`/`JsonException`) rather than an NPE.

### Fix Focus Areas
- java/src/org/openqa/selenium/remote/http/Contents.java[169-175]
- java/src/org/openqa/selenium/json/JsonInput.java[439-456]

### Suggested fix
Prefer `input.readNonNull(typeOfT)` and catch/translate the null case into a clear exception (e.g., `new JsonException("Empty request body")` or `IllegalArgumentException`). If keeping `requireNonNull`, provide a message via `requireNonNull(value, "...")` so failures are diagnosable.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@asolntsev asolntsev marked this pull request as draft April 9, 2026 05:21
@asolntsev asolntsev added this to the 4.42.0 milestone Apr 9, 2026
@asolntsev asolntsev self-assigned this Apr 9, 2026
@asolntsev asolntsev modified the milestones: 4.42.0, 4.43.0 Apr 9, 2026
@asolntsev asolntsev marked this pull request as ready for review April 11, 2026 08:00
@qodo-code-review
Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Specify nullability annotations in package org.openqa.selenium.remote and related modules

✨ Enhancement 🧪 Tests

Grey Divider

Walkthroughs

Description
  Comprehensive nullability annotation implementation across the Java codebase in the
  org.openqa.selenium.remote package and related modules.
  **Key Changes:**
• Added @NullMarked package-level annotations to establish non-nullable-by-default policy across
  multiple packages
• Systematically added @Nullable annotations to fields, parameters, and return types that can be
  null
• Replaced manual null checks with utility methods (Require.nonNull(), requireNonNull(),
  requireNonNullElse())
• Made DriverService abstract class with improved nullability handling
• Extracted helper classes (PasswordAuthenticator) and methods for better code organization
• Refactored query parameter handling with new utility methods (forEachQueryParameter(),
  getQueryString(), getQueryParameters())
• Added new test files for HttpRequest and PasswordAuthenticator classes
• Updated multiple driver service classes to make timeout parameter non-nullable
• Changed exception classes to have non-nullable parameters
• Added jspecify dependency to build configurations
• Minor code cleanups: removed unused imports, made inner classes static/final, fixed JavaDoc typos

Grey Divider

File Changes

1. java/src/org/openqa/selenium/remote/RemoteWebDriver.java ✨ Enhancement +26/-36

Specify nullability annotations in RemoteWebDriver class

• Removed @NullMarked and @NonNull annotations, replaced with explicit @Nullable on specific
 fields and methods
• Initialized previously uninitialized fields (converter, remoteLogs) at declaration time
• Added @Nullable annotations to sessionId, remoteScript, remoteNetwork fields and return
 types
• Replaced manual null checks with Require.nonNull() and requireNonNull() utility methods
• Made RemoteWebDriver() constructor initialize executor to null with
 @SuppressWarnings("DataFlowIssue")

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


2. java/test/org/openqa/selenium/remote/ProtocolHandshakeTest.java ✨ Enhancement +27/-27

Refactor ProtocolHandshakeTest with nullability and helper methods

• Added @NullMarked and @Nullable annotations to test class
• Extracted repeated HTTP response setup into createClient() helper method
• Changed RecordingHttpClient from inner class to static class with @Nullable payload field
• Updated test assertions to use assertThatThrownBy() instead of deprecated
 assertThatExceptionOfType()
• Replaced string() utility with request.contentAsString() method call

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


3. java/test/org/openqa/selenium/grid/router/TunnelWebsocketTest.java ✨ Enhancement +14/-10

Add nullability annotations to TunnelWebsocketTest

• Added @NullMarked and @Nullable annotations to test class and specific test methods
• Updated AtomicReference declarations to use @Nullable type parameters for String, URL, and
 Integer types
• Applied @NullMarked to specific test methods that require strict nullability checking

java/test/org/openqa/selenium/grid/router/TunnelWebsocketTest.java


View more (142)
4. java/src/org/openqa/selenium/remote/ErrorHandler.java ✨ Enhancement +10/-5

Add nullability annotations to ErrorHandler class

• Added @Nullable annotation to UNKNOWN_FILE constant and method return types
• Added @Nullable annotations to createUnhandledAlertException() and rebuildServerError()
 methods
• Fixed null safety check by comparing class with UnhandledAlertException.class instead of using
 equals()
• Added null check before calling Throwable.class.isAssignableFrom() on potentially null class
• Added @Nullable annotations to FrameInfoToStackFrame.apply() and toStringOrNull() methods

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


5. java/src/org/openqa/selenium/remote/AbstractDriverOptions.java ✨ Enhancement +9/-8

Update nullability in AbstractDriverOptions class

• Removed @NonNull annotation from self() method
• Changed getCapability() return type to @Nullable Object
• Added @Nullable return type annotation to getCapability() method
• Used requireNonNull() in asMap() when retrieving extra capability values
• Replaced Collections.unmodifiableMap() with static import unmodifiableMap()

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


6. java/src/org/openqa/selenium/remote/codec/AbstractHttpResponseCodec.java ✨ Enhancement +14/-13

Refactor AbstractHttpResponseCodec with improved null handling

• Replaced Objects.requireNonNullElse() with static import requireNonNullElse()
• Changed string() utility call to contentAsString() method
• Replaced Objects.requireNonNullElse() for header retrieval with new getHeader() overload
• Extracted status and state variables for improved null safety and readability
• Removed unused Objects import

java/src/org/openqa/selenium/remote/codec/AbstractHttpResponseCodec.java


7. java/src/org/openqa/selenium/remote/RemoteWebElement.java ✨ Enhancement +8/-6

Add nullability annotations to RemoteWebElement

• Added @Nullable annotation to foundBy field and getId() return type
• Replaced manual null checks with Require.nonNull() calls in sendKeys() method
• Added @Nullable type parameter to List<@Nullable File> for file detection results
• Improved error handling by using utility methods instead of inline checks

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


8. java/test/org/openqa/selenium/netty/server/WebSocketServingTest.java ✨ Enhancement +3/-46

Add nullability annotations to WebSocketServingTest

• Added @NullMarked annotation to test class and specific test methods
• Removed unused imports for MILLISECONDS, Executors, and ScheduledExecutorService
• Applied @NullMarked to shouldUseUriToChooseWhichWebSocketHandlerToUse() and
 webSocketHandlersShouldBeAbleToFireMoreThanOneMessage() methods

java/test/org/openqa/selenium/netty/server/WebSocketServingTest.java


9. java/src/org/openqa/selenium/remote/ErrorCodes.java ✨ Enhancement +5/-3

Add nullability annotations to ErrorCodes class

• Added @Nullable annotation to toState() parameter and getExceptionType() return type
• Added @Nullable annotations to toStatusCode() and isMappableError() parameters
• Improved null safety for error code mapping methods

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


10. java/src/org/openqa/selenium/Platform.java ✨ Enhancement +5/-3

Add nullability annotations to Platform class

• Added @Nullable annotations to extractFromSysProperty() method parameters
• Extracted family() call into local variable to improve null safety in is() method
• Improved readability by caching family reference before null check

java/src/org/openqa/selenium/Platform.java


11. java/src/org/openqa/selenium/remote/http/ClientConfig.java ✨ Enhancement +20/-9

Add nullability annotations to ClientConfig class

• Added @Nullable annotations to baseUri, proxy, credentials, and sslContext fields
• Added @Nullable annotations to constructor parameters and getter methods
• Refactored baseUrl() method to use Optional and extracted URL conversion to toURL() helper
• Added @Nullable return type annotations to getter methods

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


12. java/src/org/openqa/selenium/remote/service/DriverService.java ✨ Enhancement +9/-12

Make DriverService abstract with nullability improvements

• Changed DriverService from concrete class to abstract class
• Added @Nullable annotation to executable field
• Changed timeout parameter from @Nullable Duration to non-nullable Duration with default
 value
• Made getDriverProperty() and getDriverEnvironmentVariable() abstract methods
• Added @Nullable annotation to getExecutable() return type
• Added @Nullable type parameter to CompletableFuture<@Nullable StartOrDie>

java/src/org/openqa/selenium/remote/service/DriverService.java


13. java/src/org/openqa/selenium/remote/JsonToWebElementConverter.java ✨ Enhancement +5/-2

Add nullability annotations to JsonToWebElementConverter

• Added @Nullable annotation to driver field and constructor parameter
• Added @Nullable return type annotations to getElementKey() and getShadowRootKey() methods

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


14. java/src/org/openqa/selenium/remote/http/Route.java ✨ Enhancement +10/-16

Refactor Route class with final modifiers and improved null handling

• Changed inner classes to final (TemplatizedRouteConfig, TemplatizedRoute, CombinedRoute,
 PredicatedConfig, PredicatedRoute)
• Refactored query parameter iteration to use forEachQueryParameter() method
• Replaced manual null check with Require.nonNull() in PredicatedRoute.handle()

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


15. java/src/org/openqa/selenium/remote/RemoteNetwork.java Cleanup +2/-6

Remove unused BiDi field and make inner classes static

• Removed unused biDi field and related import statements
• Changed AuthDetails and RequestDetails inner classes to static classes
• Simplified constructor by removing biDi initialization

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


16. java/src/org/openqa/selenium/remote/http/jdk/JdkHttpClient.java ✨ Enhancement +5/-15

Extract PasswordAuthenticator and add nullability annotations

• Added @Nullable annotation to WebSocket listener methods
• Extracted password authentication logic into new PasswordAuthenticator class
• Simplified authenticator setup by delegating to PasswordAuthenticator

java/src/org/openqa/selenium/remote/http/jdk/JdkHttpClient.java


17. java/src/org/openqa/selenium/remote/http/HttpRequest.java ✨ Enhancement +35/-0

Add query parameter utility methods to HttpRequest

• Added @Nullable annotation to getQueryParameter() return type
• Added new methods: forEachQueryParameter(), getQueryString(), getQueryParameters()
 (overload)
• Added helper methods for query string encoding and formatting
• Added @Nullable annotation to getQueryParameters() return type

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


18. java/test/org/openqa/selenium/remote/RemoteWebDriverBuilderTest.java ✨ Enhancement +17/-1

Add nullability annotations to RemoteWebDriverBuilderTest

• Added @NullMarked and @Nullable annotations to test class and specific test methods
• Updated AtomicReference declarations to use @Nullable type parameters
• Implemented abstract methods in FakeDriverService (getDriverProperty(),
 getDriverEnvironmentVariable())

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


19. java/test/org/openqa/selenium/grid/router/HandleSessionReadTimeoutTest.java ✨ Enhancement +5/-5

Add nullability annotations to HandleSessionReadTimeoutTest

• Added @Nullable annotation to AtomicReference<@Nullable Duration> declarations
• Removed throws Exception from runSingleRequest() method signature

java/test/org/openqa/selenium/grid/router/HandleSessionReadTimeoutTest.java


20. java/src/org/openqa/selenium/remote/WebElementToJsonConverter.java ✨ Enhancement +5/-3

Add nullability annotations to WebElementToJsonConverter

• Updated Function interface type parameters to include @Nullable annotations
• Added @Nullable annotation to apply() method parameter and return type
• Added @Nullable type parameter to Map<String, @Nullable Object> for converted values

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


21. java/src/org/openqa/selenium/remote/http/UrlTemplate.java ✨ Enhancement +8/-8

Add nullability annotations to UrlTemplate class

• Fixed regex pattern for group name matching
• Added @Nullable annotation to compiled function return type
• Replaced manual null check with Require.nonEmpty() in constructor
• Added @Nullable annotations to match() method parameters and return types
• Changed Match inner class to static final class

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


22. java/src/org/openqa/selenium/remote/codec/w3c/W3CHttpResponseCodec.java ✨ Enhancement +5/-3

Improve null safety in W3CHttpResponseCodec

• Added @Nullable annotation to Object array in logging statement
• Extracted response.getValue() into local variable for improved null safety

java/src/org/openqa/selenium/remote/codec/w3c/W3CHttpResponseCodec.java


23. java/src/org/openqa/selenium/remote/RemoteWebDriverBuilder.java ✨ Enhancement +5/-5

Add nullability annotations to RemoteWebDriverBuilder

• Added @Nullable annotations to remoteHost, driverService, and credentials fields
• Removed throws clause from sendNative() method signature
• Added @Nullable annotation to startDriverServiceIfNecessary() return type

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


24. java/src/org/openqa/selenium/json/Json.java ✨ Enhancement +3/-2

Add nullability annotations to Json class

• Added @Nullable annotation to toJson() method parameters

java/src/org/openqa/selenium/json/Json.java


25. java/test/org/openqa/selenium/remote/http/HttpRequestTest.java 🧪 Tests +43/-0

Add tests for HttpRequest query string methods

• New test file for HttpRequest class
• Tests for getQueryString() method with multiple and single query parameters
• Tests for empty query string scenario

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


26. java/src/org/openqa/selenium/support/pagefactory/AjaxElementLocator.java ✨ Enhancement +9/-4

Add nullability annotations to AjaxElementLocator

• Added @Nullable annotations to lastException and element fields in SlowLoadingElement
• Added @Nullable annotations to getter methods returning nullable values
• Added @Nullable annotations to lastException and elements fields in SlowLoadingElementList

java/src/org/openqa/selenium/support/pagefactory/AjaxElementLocator.java


27. java/src/org/openqa/selenium/remote/UnreachableBrowserException.java ✨ Enhancement +2/-5

Remove NullMarked and make parameters non-nullable

• Removed @NullMarked class-level annotation
• Changed constructor parameters from @Nullable String to non-nullable String
• Changed Throwable parameter from @Nullable to non-nullable in second constructor

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


28. java/test/org/openqa/selenium/remote/http/jdk/PasswordAuthenticatorTest.java 🧪 Tests +41/-0

Add tests for PasswordAuthenticator class

• New test file for PasswordAuthenticator class
• Tests for username and password parsing from userInfo string
• Tests for username without password scenario

java/test/org/openqa/selenium/remote/http/jdk/PasswordAuthenticatorTest.java


29. java/src/org/openqa/selenium/remote/Command.java ✨ Enhancement +6/-3

Add nullability annotations to Command class

• Added @Nullable annotation to sessionId field and constructor parameters
• Added @Nullable annotation to getSessionId() return type
• Added //noinspection DataFlowIssue comment for null safety

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


30. java/src/org/openqa/selenium/remote/http/jdk/JdkHttpMessages.java Cleanup +1/-17

Simplify query string handling in JdkHttpMessages

• Removed unused imports for URL encoding and stream utilities
• Replaced inline query string building with req.getQueryString() method call

java/src/org/openqa/selenium/remote/http/jdk/JdkHttpMessages.java


31. java/src/org/openqa/selenium/remote/W3CHandshakeResponse.java ✨ Enhancement +3/-2

Add nullability annotations to W3CHandshakeResponse

• Added @Nullable annotation to Function return types in errorHandler() and successHandler()

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


32. java/src/org/openqa/selenium/remote/http/jdk/PasswordAuthenticator.java ✨ Enhancement +37/-0

Add PasswordAuthenticator class for HTTP authentication

• New class for handling HTTP Basic Authentication
• Parses username and password from userInfo string
• Extends Authenticator and provides PasswordAuthentication

java/src/org/openqa/selenium/remote/http/jdk/PasswordAuthenticator.java


33. java/test/org/openqa/selenium/remote/http/HttpClientFactoryTest.java ✨ Enhancement +7/-3

Add nullability annotations to HttpClientFactoryTest

• Added @NullMarked annotation to test factory classes
• Changed factory implementations to throw UnsupportedOperationException instead of returning null

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


34. java/test/org/openqa/selenium/remote/AugmenterTest.java ✨ Enhancement +6/-1

Add nullability annotations to AugmenterTest

• Added @NullMarked annotation to test class and inner classes
• Changed findElement() to throw NoSuchElementException instead of returning null

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


35. java/src/org/openqa/selenium/remote/tracing/opentelemetry/OpenTelemetryPropagator.java ✨ Enhancement +5/-3

Add nullability annotations to OpenTelemetryPropagator

• Added @Nullable annotations to BiFunction type parameters
• Updated TextMapGetter anonymous class with @Nullable annotations
• Simplified generic type declaration using diamond operator

java/src/org/openqa/selenium/remote/tracing/opentelemetry/OpenTelemetryPropagator.java


36. java/test/org/openqa/selenium/environment/webserver/NettyAppServer.java ✨ Enhancement +7/-3

Add nullability annotations to NettyAppServer

• Added @Nullable annotations to server and secure fields
• Added null check in stop() method before calling server.stop()
• Added @Nullable annotation to getAlternateHostName() return type

java/test/org/openqa/selenium/environment/webserver/NettyAppServer.java


37. java/src/org/openqa/selenium/remote/ScreenshotException.java ✨ Enhancement +3/-5

Remove NullMarked and make parameters non-nullable

• Removed @NullMarked class-level annotation
• Changed constructor parameters from @Nullable String to non-nullable String
• Kept @Nullable annotation only on Throwable parameter in third constructor

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


38. java/src/org/openqa/selenium/remote/HttpCommandExecutor.java ✨ Enhancement +3/-2

Add nullability annotations to HttpCommandExecutor

• Added @Nullable annotations to commandCodec and responseCodec fields

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


39. java/src/org/openqa/selenium/remote/tracing/opentelemetry/OpenTelemetryTracer.java ✨ Enhancement +3/-2

Add nullability annotations to OpenTelemetryTracer

• Added @Nullable annotation to singleton static field
• Added @Nullable annotation to context field

java/src/org/openqa/selenium/remote/tracing/opentelemetry/OpenTelemetryTracer.java


40. java/src/org/openqa/selenium/remote/HandshakeResponse.java ✨ Enhancement +5/-3

Add nullability annotations to HandshakeResponse interface

• Added @Nullable annotations to Function return types in interface methods

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


41. java/src/org/openqa/selenium/remote/CommandPayload.java ✨ Enhancement +3/-4

Remove NullMarked and add parameter validation

• Removed @NullMarked class-level annotation
• Added Require.nonNull() calls in constructor to validate name and parameters

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


42. java/src/org/openqa/selenium/remote/http/AddSeleniumUserAgent.java ✨ Enhancement +9/-7

Refactor AddSeleniumUserAgent with improved null handling

• Extracted platform label calculation into platformLabel() helper method
• Used requireNonNullElse() to handle null platform family
• Replaced Locale.US with static import ROOT

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


43. java/src/org/openqa/selenium/remote/ProtocolHandshake.java ✨ Enhancement +2/-1

Add nullability annotations to ProtocolHandshake

• Added @Nullable annotation to massageProxy function return type

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


44. java/test/org/openqa/selenium/testing/drivers/OutOfProcessSeleniumServer.java ✨ Enhancement +4/-3

Add nullability annotations to OutOfProcessSeleniumServer

• Added @Nullable annotations to baseUrl and process fields with null initialization
• Changed filter condition from Objects::nonNull to explicit non-empty string check

java/test/org/openqa/selenium/testing/drivers/OutOfProcessSeleniumServer.java


45. java/src/org/openqa/selenium/devtools/Connection.java ✨ Enhancement +2/-0

Add nullability annotations to Connection class

• Added @NullMarked annotation to inner Listener class

java/src/org/openqa/selenium/devtools/Connection.java


46. java/test/org/openqa/selenium/support/pagefactory/AnnotationsTest.java ✨ Enhancement +5/-2

Add nullability annotations to AnnotationsTest

• Added @NullMarked annotation to FindByXXXXBuilder inner class
• Changed findElements() to return emptyList() instead of null
• Updated generic type parameter for AbstractFindByBuilder<Object>

java/test/org/openqa/selenium/support/pagefactory/AnnotationsTest.java


47. java/src/org/openqa/selenium/ie/InternetExplorerDriverService.java ✨ Enhancement +2/-2

Make timeout parameter non-nullable in InternetExplorerDriverService

• Changed timeout parameter from @Nullable Duration to non-nullable Duration

java/src/org/openqa/selenium/ie/InternetExplorerDriverService.java


48. java/src/org/openqa/selenium/remote/tracing/opentelemetry/package-info.java ✨ Enhancement +21/-0

Add package-info with NullMarked annotation

• New package-info file with @NullMarked annotation

java/src/org/openqa/selenium/remote/tracing/opentelemetry/package-info.java


49. java/src/org/openqa/selenium/chrome/ChromeDriverService.java ✨ Enhancement +2/-2

Make timeout parameter non-nullable in ChromeDriverService

• Changed timeout parameter from @Nullable Duration to non-nullable Duration

java/src/org/openqa/selenium/chrome/ChromeDriverService.java


50. java/src/org/openqa/selenium/edge/EdgeDriverService.java ✨ Enhancement +2/-2

Make timeout parameter non-nullable in EdgeDriverService

• Changed timeout parameter from @Nullable Duration to non-nullable Duration

java/src/org/openqa/selenium/edge/EdgeDriverService.java


51. java/src/org/openqa/selenium/remote/codec/w3c/package-info.java ✨ Enhancement +21/-0

Add package-info with NullMarked annotation

• New package-info file with @NullMarked annotation

java/src/org/openqa/selenium/remote/codec/w3c/package-info.java


52. java/src/org/openqa/selenium/remote/tracing/empty/package-info.java ✨ Enhancement +21/-0

Add package-info with NullMarked annotation

• New package-info file with @NullMarked annotation

java/src/org/openqa/selenium/remote/tracing/empty/package-info.java


53. java/src/org/openqa/selenium/remote/http/jdk/package-info.java ✨ Enhancement +21/-0

Add package-info with NullMarked annotation

• New package-info file with @NullMarked annotation

java/src/org/openqa/selenium/remote/http/jdk/package-info.java


54. java/src/org/openqa/selenium/remote/service/DriverFinder.java ✨ Enhancement +3/-1

Add nullability annotations to DriverFinder

• Added @Nullable annotation to result field
• Added @Nullable annotation to getBrowserBinary() method return type

java/src/org/openqa/selenium/remote/service/DriverFinder.java


55. java/src/org/openqa/selenium/remote/locators/package-info.java ✨ Enhancement +21/-0

Add package-info with NullMarked annotation

• New package-info file with @NullMarked annotation

java/src/org/openqa/selenium/remote/locators/package-info.java


56. java/src/org/openqa/selenium/support/pagefactory/internal/package-info.java ✨ Enhancement +21/-0

Add package-info with NullMarked annotation

• New package-info file with @NullMarked annotation

java/src/org/openqa/selenium/support/pagefactory/internal/package-info.java


57. java/src/org/openqa/selenium/remote/tracing/package-info.java ✨ Enhancement +21/-0

Add package-info with NullMarked annotation

• New package-info file with @NullMarked annotation

java/src/org/openqa/selenium/remote/tracing/package-info.java


58. java/src/org/openqa/selenium/support/locators/package-info.java ✨ Enhancement +21/-0

Add package-info with NullMarked annotation

• New package-info file with @NullMarked annotation

java/src/org/openqa/selenium/support/locators/package-info.java


59. java/src/org/openqa/selenium/remote/codec/package-info.java ✨ Enhancement +21/-0

Add package-info with NullMarked annotation

• New package-info file with @NullMarked annotation

java/src/org/openqa/selenium/remote/codec/package-info.java


60. java/src/org/openqa/selenium/support/decorators/package-info.java ✨ Enhancement +21/-0

Add package-info with NullMarked annotation

• New package-info file with @NullMarked annotation

java/src/org/openqa/selenium/support/decorators/package-info.java


61. java/src/org/openqa/selenium/support/pagefactory/package-info.java ✨ Enhancement +21/-0

Add package-info with NullMarked annotation

• New package-info file with @NullMarked annotation

java/src/org/openqa/selenium/support/pagefactory/package-info.java


62. java/test/org/openqa/selenium/environment/webserver/package-info.java ✨ Enhancement +21/-0

Add package-info with NullMarked annotation

• New package-info file with @NullMarked annotation

java/test/org/openqa/selenium/environment/webserver/package-info.java


63. java/src/org/openqa/selenium/remote/http/package-info.java ✨ Enhancement +21/-0

Add package-info with NullMarked annotation

• New package-info file with @NullMarked annotation

java/src/org/openqa/selenium/remote/http/package-info.java


64. java/src/org/openqa/selenium/remote/service/package-info.java ✨ Enhancement +21/-0

Add package-info with NullMarked annotation

• New package-info file with @NullMarked annotation

java/src/org/openqa/selenium/remote/service/package-info.java


65. java/src/org/openqa/selenium/support/events/package-info.java ✨ Enhancement +21/-0

Add package-info with NullMarked annotation

• New package-info file with @NullMarked annotation

java/src/org/openqa/selenium/support/events/package-info.java


66. java/test/org/openqa/selenium/grid/testing/package-info.java ✨ Enhancement +21/-0

Add package-info with NullMarked annotation

• New package-info file with @NullMarked annotation

java/test/org/openqa/selenium/grid/testing/package-info.java


67. java/src/org/openqa/selenium/remote/package-info.java ✨ Enhancement +21/-0

Add package-info with NullMarked annotation

• New package-info file with @NullMarked annotation

java/src/org/openqa/selenium/remote/package-info.java


68. java/test/org/openqa/selenium/environment/webserver/CookieHandler.java ✨ Enhancement +4/-2

Add nullability annotations to CookieHandler

• Added @Nullable annotation to generic type parameter in append() method
• Added @Nullable annotation to escapeCookieValue() method parameter

java/test/org/openqa/selenium/environment/webserver/CookieHandler.java


69. java/src/org/openqa/selenium/support/package-info.java ✨ Enhancement +21/-0

Add package-info with NullMarked annotation

• New package-info file with @NullMarked annotation

java/src/org/openqa/selenium/support/package-info.java


70. java/test/org/openqa/selenium/environment/package-info.java ✨ Enhancement +21/-0

Add package-info with NullMarked annotation

• New package-info file with @NullMarked annotation

java/test/org/openqa/selenium/environment/package-info.java


71. java/src/org/openqa/selenium/grid/web/ReverseProxyHandler.java Cleanup +4/-5

Simplify query parameter handling in ReverseProxyHandler

• Refactored query parameter iteration to use forEachQueryParameter() method

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


72. java/src/org/openqa/selenium/remote/http/HttpMessage.java ✨ Enhancement +6/-0

Add nullability and header utility methods to HttpMessage

• Added @Nullable annotation to getAttribute() return type
• Added new getHeader() overload accepting HttpHeader enum and default value

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


73. java/test/org/openqa/selenium/environment/webserver/AppServerTestBase.java ✨ Enhancement +6/-2

Add nullability annotations to AppServerTestBase

• Added @Nullable annotation to driver static field with null initialization
• Added null check in quitDriver() before calling driver.quit()

java/test/org/openqa/selenium/environment/webserver/AppServerTestBase.java


74. java/test/org/openqa/selenium/remote/internal/WebSocketTestBase.java ✨ Enhancement +3/-0

Add nullability annotations to WebSocketTestBase

• Added @NullMarked annotation to WebSocket listener methods

java/test/org/openqa/selenium/remote/internal/WebSocketTestBase.java


75. java/src/org/openqa/selenium/remote/service/DriverCommandExecutor.java ✨ Enhancement +3/-2

Add nullability annotations to DriverCommandExecutor

• Added @Nullable type parameters to CompletableFuture<@Nullable Response> declarations

java/src/org/openqa/selenium/remote/service/DriverCommandExecutor.java


76. java/src/org/openqa/selenium/remote/DesiredCapabilities.java ✨ Enhancement +1/-1

Make merge parameter non-nullable in DesiredCapabilities

• Changed merge() method parameter from @Nullable Capabilities to non-nullable Capabilities

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


77. java/test/org/openqa/selenium/support/events/EventFiringDecoratorTest.java ✨ Enhancement +3/-0

Add nullability annotations to EventFiringDecoratorTest

• Added @NullMarked annotation to test class and specific test methods

java/test/org/openqa/selenium/support/events/EventFiringDecoratorTest.java


78. java/test/org/openqa/selenium/environment/GlobalTestEnvironment.java ✨ Enhancement +5/-2

Add nullability annotations to GlobalTestEnvironment

• Added @Nullable annotation to environment static field with null initialization
• Changed get() method to use requireNonNull() with error message

java/test/org/openqa/selenium/environment/GlobalTestEnvironment.java


79. java/test/org/openqa/selenium/remote/internal/HttpClientTestBase.java Cleanup +1/-6

Simplify query parameter handling in HttpClientTestBase

• Removed unused TreeMap import
• Simplified query parameter response by using req.getQueryParameters() directly

java/test/org/openqa/selenium/remote/internal/HttpClientTestBase.java


80. java/src/org/openqa/selenium/firefox/FirefoxDriverService.java ✨ Enhancement +1/-1

Make timeout parameter non-nullable in FirefoxDriverService

• Changed timeout parameter from @Nullable Duration to non-nullable Duration

java/src/org/openqa/selenium/firefox/FirefoxDriverService.java


81. java/test/org/openqa/selenium/environment/webserver/AppServer.java ✨ Enhancement +3/-1

Add nullability annotations to AppServer interface

• Added @Nullable annotation to getAlternateHostName() return type
• Added @Nullable annotation to detectAlternateHostname() static method return type

java/test/org/openqa/selenium/environment/webserver/AppServer.java


82. java/src/org/openqa/selenium/remote/tracing/empty/NullPropagator.java ✨ Enhancement +2/-1

Add nullability annotations to NullPropagator

• Added @Nullable annotation to BiFunction return type parameter

java/src/org/openqa/selenium/remote/tracing/empty/NullPropagator.java


83. java/src/org/openqa/selenium/support/events/EventFiringDecorator.java ✨ Enhancement +2/-0

Add nullability annotations to EventFiringDecorator

• Added @Nullable annotation to findMatchingMethod() return type

java/src/org/openqa/selenium/support/events/EventFiringDecorator.java


84. java/src/org/openqa/selenium/remote/http/Contents.java ✨ Enhancement +2/-1

Add null safety to Contents.fromJson method

• Added requireNonNull() call in fromJson() method to ensure non-null result

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


85. java/test/org/openqa/selenium/grid/distributor/local/LocalDistributorTest.java ✨ Enhancement +2/-1

Add nullability annotations to LocalDistributorTest

• Added @Nullable type parameter to List<Callable<@Nullable SessionId>>

java/test/org/openqa/selenium/grid/distributor/local/LocalDistributorTest.java


86. java/test/org/openqa/selenium/environment/webserver/SleepingHandler.java ✨ Enhancement +3/-1

Add null safety to SleepingHandler

• Added requireNonNull() call with error message for required query parameter

java/test/org/openqa/selenium/environment/webserver/SleepingHandler.java


87. java/src/org/openqa/selenium/remote/tracing/HttpTracing.java ✨ Enhancement +2/-1

Add nullability annotations to HttpTracing

• Added @Nullable annotation to inject() method context parameter

java/src/org/openqa/selenium/remote/tracing/HttpTracing.java


88. java/src/org/openqa/selenium/support/pagefactory/DefaultElementLocator.java ✨ Enhancement +3/-2

Add nullability annotations to DefaultElementLocator

• Added @Nullable annotations to cachedElement and cachedElementList fields

java/src/org/openqa/selenium/support/pagefactory/DefaultElementLocator.java


89. java/src/org/openqa/selenium/support/locators/RelativeLocator.java ✨ Enhancement +2/-1

Add null safety to RelativeLocator

• Added requireNonNull() call to ensure non-null elements list from script execution

java/src/org/openqa/selenium/support/locators/RelativeLocator.java


90. java/src/org/openqa/selenium/support/locators/RelativeLocatorServerSide.java ✨ Enhancement +2/-1

Add null safety to RelativeLocatorServerSide

• Added requireNonNull() call to ensure non-null elements list from script execution

java/src/org/openqa/selenium/support/locators/RelativeLocatorServerSide.java


91. java/src/org/openqa/selenium/remote/http/HttpResponse.java ✨ Enhancement +3/-0

Add nullability annotations to HttpResponse

• Added @Nullable annotation to getTargetHost() return type

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


92. java/src/org/openqa/selenium/safari/SafariDriverService.java ✨ Enhancement +2/-2

Mark timeout parameter as non-nullable

• Removed @Nullable annotation from Duration timeout parameter in constructor, marking it as
 non-nullable
• Removed @Nullable annotation from Duration timeout parameter in createDriverService method

java/src/org/openqa/selenium/safari/SafariDriverService.java


93. java/src/org/openqa/selenium/remote/tracing/Propagator.java ✨ Enhancement +2/-1

Add nullability annotation to getter return type

• Added import for org.jspecify.annotations.Nullable
• Added @Nullable annotation to the return type of BiFunction getter in extractContext method

java/src/org/openqa/selenium/remote/tracing/Propagator.java


94. java/src/org/openqa/selenium/support/pagefactory/DefaultFieldDecorator.java ✨ Enhancement +2/-0

Mark decorate method return as nullable

• Added import for org.jspecify.annotations.Nullable
• Added @Nullable annotation to decorate method return type

java/src/org/openqa/selenium/support/pagefactory/DefaultFieldDecorator.java


95. java/test/org/openqa/selenium/remote/http/NativeHttpClientMethodsTest.java ✨ Enhancement +2/-0

Apply NullMarked annotation to test class

• Added import for org.jspecify.annotations.NullMarked
• Added @NullMarked annotation to TestHttpClient inner class

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


96. java/src/org/openqa/selenium/remote/http/ConnectionFailedException.java ✨ Enhancement +2/-5

Mark exception parameters as non-nullable

• Removed @NullMarked and @Nullable annotations from class and constructors
• Changed constructor parameters from @Nullable String message to non-nullable String message
• Changed constructor parameter from @Nullable Throwable cause to non-nullable Throwable cause

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


97. java/src/org/openqa/selenium/support/AbstractFindByBuilder.java ✨ Enhancement...

@qodo-code-review
Copy link
Copy Markdown
Contributor

qodo-code-review bot commented Apr 11, 2026

Code Review by Qodo

🐞 Bugs (3)   📘 Rule violations (3)   📎 Requirement gaps (0)   🎨 UX Issues (0)
🐞\ ≡ Correctness (2) ☼ Reliability (1) ⭐ New (1)
📘\ ⚙ Maintainability (3) ⭐ New (1)

Grey Divider


Action required

1. @NullMarked alters public nullability 📘
Description
The PR introduces jspecify nullness defaults (@NullMarked) and new @Nullable annotations on
public APIs, which changes the published nullability contract and can break source compatibility for
consumers (notably Kotlin) when upgrading. This conflicts with the requirement to maintain
backward-compatible public interfaces.
Code

java/src/org/openqa/selenium/remote/package-info.java[R18-21]

+@NullMarked
+package org.openqa.selenium.remote;
+
+import org.jspecify.annotations.NullMarked;
Evidence
PR Compliance ID 1 requires public API changes to remain backward-compatible; adding package-level
@NullMarked and new nullability annotations changes the externally visible API contract for these
packages/methods and may cause consumer compilation failures on upgrade.

AGENTS.md
java/src/org/openqa/selenium/remote/package-info.java[18-21]
java/src/org/openqa/selenium/Platform.java[419-435]
java/src/org/openqa/selenium/remote/RemoteWebDriver.java[835-836]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
New jspecify nullability defaults/annotations change public API nullness contracts, which can be a source-breaking change for downstream users (notably Kotlin) and violates the compatibility requirement.

## Issue Context
`@NullMarked` makes all unannotated types non-null by default for the package, and adding `@Nullable`/non-null defaults to existing public APIs changes what downstream compilers/static analyzers accept.

## Fix Focus Areas
- java/src/org/openqa/selenium/remote/package-info.java[18-21]
- java/src/org/openqa/selenium/Platform.java[419-435]
- java/src/org/openqa/selenium/remote/RemoteWebDriver.java[835-836]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Null baseUri dereference 🐞
Description
JdkHttpClient/JdkHttpMessages dereference config.baseUri() even though
ClientConfig.defaultConfig() initializes baseUri to null and baseUri() is annotated @Nullable.
Creating an HTTP client with a ClientConfig that hasn’t had baseUri/baseUrl set can throw
NullPointerException during client construction or request URI resolution.
Code

java/src/org/openqa/selenium/remote/http/jdk/JdkHttpClient.java[113]

    String info = config.baseUri().getUserInfo();
Evidence
ClientConfig.defaultConfig() constructs a config with baseUri=null and the accessor is
explicitly @Nullable, but both JdkHttpClient and JdkHttpMessages immediately dereference
config.baseUri() without a null-guard (e.g., calling getUserInfo() / toString()), which will
NPE if a caller uses HttpClient.Factory.createClient(ClientConfig) with an unset config.

java/src/org/openqa/selenium/remote/http/ClientConfig.java[89-100]
java/src/org/openqa/selenium/remote/http/ClientConfig.java[138-146]
java/src/org/openqa/selenium/remote/http/jdk/JdkHttpClient.java[112-116]
java/src/org/openqa/selenium/remote/http/jdk/JdkHttpMessages.java[123-140]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`ClientConfig.baseUri()` is documented/annotated as nullable and `ClientConfig.defaultConfig()` sets it to `null`, but `JdkHttpClient` and `JdkHttpMessages` dereference it without validation. This creates a runtime NPE hazard for callers that construct an `HttpClient` from a `ClientConfig` that hasn’t been finalized with `.baseUri(...)`/`.baseUrl(...)`.

### Issue Context
The PR is making nullness contracts explicit via `@NullMarked` + `@Nullable`. Once `baseUri()` is nullable, all code paths that dereference it must either:
- enforce that it’s set (fail fast with a clear error), or
- implement a meaningful fallback behavior.

### Fix Focus Areas
- java/src/org/openqa/selenium/remote/http/jdk/JdkHttpClient.java[112-116]
- java/src/org/openqa/selenium/remote/http/jdk/JdkHttpMessages.java[123-140]
- (optional hardening) java/src/org/openqa/selenium/remote/HttpCommandExecutor.java[111-120]

### Suggested fix
1. In `JdkHttpClient` constructor, fetch and validate once, then use the validated value:
  - `URI baseUri = Require.nonNull("Base URI", config.baseUri());`
  - use `baseUri.getUserInfo()` instead of `config.baseUri().getUserInfo()`.
2. In `JdkHttpMessages.getRawUri`, validate `config.baseUri()` before calling `toString()`:
  - `URI baseUrl = Require.nonNull("Base URI", config.baseUri());`
3. (Optional) In `HttpCommandExecutor`’s `(ClientConfig, Factory)` constructor, validate `config.baseUrl()` / `config.baseUri()` so the executor cannot be created in an unusable state, and the failure mode is a clear `IllegalArgumentException` rather than a later NPE.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. DriverService made abstract 📘
Description
DriverService was changed from a concrete class to an abstract class and now has new abstract
methods, which is a public API/ABI breaking change for any downstream code that instantiated it or
extended it without implementing the new abstract methods. This violates the requirement to preserve
backward compatibility or deprecate before breaking changes.
Code

java/src/org/openqa/selenium/remote/service/DriverService.java[R64-65]

+public abstract class DriverService implements Closeable {
Evidence
PR Compliance ID 1 forbids introducing breaking changes to public API/ABI without a deprecation
period. The diff changes DriverService to abstract and changes
getDriverProperty()/getDriverEnvironmentVariable() from default implementations to abstract
methods, which breaks existing subclasses and removes the ability to instantiate DriverService
directly.

AGENTS.md
java/src/org/openqa/selenium/remote/service/DriverService.java[64-65]
java/src/org/openqa/selenium/remote/service/DriverService.java[156-159]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`DriverService` was changed in a binary/source incompatible way (`class` � `abstract class`, and previously non-abstract methods now `abstract`). This can break downstream consumers at compile time and runtime.

## Issue Context
This PR is primarily about nullability. The compatibility policy requires either preserving public API/ABI or providing a deprecation/migration path before introducing breaking changes.

## Fix Focus Areas
- java/src/org/openqa/selenium/remote/service/DriverService.java[64-65]
- java/src/org/openqa/selenium/remote/service/DriverService.java[156-159]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (1)
4. Invalid query map return 🐞
Description
HttpRequest#getQueryParameters() declares Map<String, Iterable<String>> but returns an
unmodifiable view of a Map<String, List<String>>, which is not assignment-compatible due to
generic invariance and should not compile.
Code

java/src/org/openqa/selenium/remote/http/HttpRequest.java[R104-106]

+  public Map<String, Iterable<String>> getQueryParameters() {
+    return Collections.unmodifiableMap(queryParameters);
+  }
Evidence
The backing field is Map<String, List<String>>, but the method return type is `Map<String,
Iterable<String>>` with no wildcard/cast, so the return expression type cannot satisfy the declared
return type.

java/src/org/openqa/selenium/remote/http/HttpRequest.java[37-40]
java/src/org/openqa/selenium/remote/http/HttpRequest.java[104-106]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`HttpRequest#getQueryParameters()` returns `Collections.unmodifiableMap(queryParameters)` where `queryParameters` is `Map<String, List<String>>`, but the method signature declares `Map<String, Iterable<String>>`. This is not type-compatible in Java and should fail compilation.

### Issue Context
This method was added to support callers that want the full query-parameter multimap.

### Fix Focus Areas
- java/src/org/openqa/selenium/remote/http/HttpRequest.java[37-40]
- java/src/org/openqa/selenium/remote/http/HttpRequest.java[104-106]

### Suggested fix
Use one of:
- Change signature to `public Map<String, List<String>> getQueryParameters()` (and keep returning `Collections.unmodifiableMap(queryParameters)`), or
- Keep the abstraction but make it type-correct: `public Map<String, ? extends Iterable<String>> getQueryParameters()`.
Then update any call sites/tests accordingly.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

5. Repo-wide nullability churn 📘
Description
The PR makes widespread, noisy changes across many packages and tests (e.g., adding
package-info.java with @NullMarked and unrelated edits), which increases review/revert risk
beyond the stated scope. This violates the preference for small, reversible diffs over broad
refactors/reformatting.
Code

java/src/org/openqa/selenium/remote/package-info.java[R1-21]

+// Licensed to the Software Freedom Conservancy (SFC) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The SFC licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+@NullMarked
+package org.openqa.selenium.remote;
+
+import org.jspecify.annotations.NullMarked;
Evidence
PR Compliance ID 2 requires narrowly scoped changes and discourages broad, noisy refactors. The diff
shows numerous cross-cutting changes outside a single tightly-scoped area, including adding multiple
package-info.java files and unrelated edits (e.g., Safari javadoc text), increasing churn not
strictly required for a focused fix.

AGENTS.md
java/src/org/openqa/selenium/remote/package-info.java[1-21]
java/src/org/openqa/selenium/support/package-info.java[1-21]
java/test/org/openqa/selenium/environment/package-info.java[1-21]
java/src/org/openqa/selenium/safari/SafariDriver.java[46-46]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
This PR introduces broad churn across many packages (multiple `package-info.java` additions and unrelated edits), reducing reviewability and increasing revert risk.

## Issue Context
Compliance requires changes to be narrowly scoped and reversible; wide refactors should be split or minimized to only what is necessary for the intended change.

## Fix Focus Areas
- java/src/org/openqa/selenium/remote/package-info.java[1-21]
- java/src/org/openqa/selenium/support/package-info.java[1-21]
- java/test/org/openqa/selenium/environment/package-info.java[1-21]
- java/src/org/openqa/selenium/safari/SafariDriver.java[46-46]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. NPE on empty JSON body 🐞
Description
Contents.fromJson now wraps JsonInput.read with requireNonNull, which throws
NullPointerException when the message body is empty/exhausted because JsonInput.read(Type)
explicitly returns null at EOF.
Code

java/src/org/openqa/selenium/remote/http/Contents.java[R169-172]

  public static <T> T fromJson(HttpMessage<?> message, Type typeOfT) {
    try (Reader reader = reader(message);
        JsonInput input = JSON.newInput(reader)) {
-      return input.read(typeOfT);
+      return requireNonNull(input.read(typeOfT));
Evidence
JsonInput.read(Type) is annotated nullable and returns null when the input is exhausted (EOF).
Contents.fromJson now unconditionally requireNonNull(...)s that value, converting an empty body
into an NPE (often reported as a 500) rather than a structured decode/validation error.

java/src/org/openqa/selenium/remote/http/Contents.java[169-175]
java/src/org/openqa/selenium/json/JsonInput.java[439-456]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`Contents.fromJson` throws a `NullPointerException` on empty request bodies because it calls `requireNonNull(input.read(typeOfT))` and `JsonInput.read` returns null on EOF.

### Issue Context
This method is used by HTTP handlers parsing request bodies (e.g., Grid endpoints). Empty bodies should ideally map to a controlled client error (e.g., `IllegalArgumentException`/`JsonException`) rather than an NPE.

### Fix Focus Areas
- java/src/org/openqa/selenium/remote/http/Contents.java[169-175]
- java/src/org/openqa/selenium/json/JsonInput.java[439-456]

### Suggested fix
Prefer `input.readNonNull(typeOfT)` and catch/translate the null case into a clear exception (e.g., `new JsonException("Empty request body")` or `IllegalArgumentException`). If keeping `requireNonNull`, provide a message via `requireNonNull(value, "...")` so failures are diagnosable.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@@ -111,18 +112,7 @@ public class JdkHttpClient implements HttpClient {
Credentials credentials = config.credentials();
String info = config.baseUri().getUserInfo();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Action required

2. Null baseuri dereference 🐞 Bug ≡ Correctness

JdkHttpClient/JdkHttpMessages dereference config.baseUri() even though
ClientConfig.defaultConfig() initializes baseUri to null and baseUri() is annotated @Nullable.
Creating an HTTP client with a ClientConfig that hasn’t had baseUri/baseUrl set can throw
NullPointerException during client construction or request URI resolution.
Agent Prompt
### Issue description
`ClientConfig.baseUri()` is documented/annotated as nullable and `ClientConfig.defaultConfig()` sets it to `null`, but `JdkHttpClient` and `JdkHttpMessages` dereference it without validation. This creates a runtime NPE hazard for callers that construct an `HttpClient` from a `ClientConfig` that hasn’t been finalized with `.baseUri(...)`/`.baseUrl(...)`.

### Issue Context
The PR is making nullness contracts explicit via `@NullMarked` + `@Nullable`. Once `baseUri()` is nullable, all code paths that dereference it must either:
- enforce that it’s set (fail fast with a clear error), or
- implement a meaningful fallback behavior.

### Fix Focus Areas
- java/src/org/openqa/selenium/remote/http/jdk/JdkHttpClient.java[112-116]
- java/src/org/openqa/selenium/remote/http/jdk/JdkHttpMessages.java[123-140]
- (optional hardening) java/src/org/openqa/selenium/remote/HttpCommandExecutor.java[111-120]

### Suggested fix
1. In `JdkHttpClient` constructor, fetch and validate once, then use the validated value:
   - `URI baseUri = Require.nonNull("Base URI", config.baseUri());`
   - use `baseUri.getUserInfo()` instead of `config.baseUri().getUserInfo()`.
2. In `JdkHttpMessages.getRawUri`, validate `config.baseUri()` before calling `toString()`:
   - `URI baseUrl = Require.nonNull("Base URI", config.baseUri());`
3. (Optional) In `HttpCommandExecutor`’s `(ClientConfig, Factory)` constructor, validate `config.baseUrl()` / `config.baseUri()` so the executor cannot be created in an unusable state, and the failure mode is a clear `IllegalArgumentException` rather than a later NPE.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@asolntsev asolntsev force-pushed the nullability branch 2 times, most recently from a9b5e20 to cf1965a Compare April 11, 2026 11:53
* Mark everything as non-nullable by default, and
* Mark only the needed methods/parameters as nullable.

Partially implements SeleniumHQ#14291
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

B-build Includes scripting, bazel and CI integrations B-devtools Includes everything BiDi or Chrome DevTools related B-grid Everything grid and server related B-support Issue or PR related to support classes C-java Java Bindings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants