Skip to content

[java] specify nullability in other java packages - #17194

Merged
asolntsev merged 8 commits into
SeleniumHQ:trunkfrom
asolntsev:nullability
Mar 12, 2026
Merged

[java] specify nullability in other java packages#17194
asolntsev merged 8 commits into
SeleniumHQ:trunkfrom
asolntsev:nullability

Conversation

@asolntsev

@asolntsev asolntsev commented Mar 9, 2026

Copy link
Copy Markdown
Contributor

🔗 Related Issues

Partially implements #14291

💥 What does this PR do?

Adds JSpecify nullability annotations to other packages:

  • org.openqa.selenium.events.*
  • org.openqa.selenium.interactions.*
  • org.openqa.selenium.netty.*
  • org.openqa.selenium.redis.*
  • org.openqa.selenium.status.*
  • org.openqa.selenium.virtualauthenticator.*

🔄 Types of changes

  • Cleanup (formatting, renaming)

@asolntsev asolntsev self-assigned this Mar 9, 2026
@asolntsev asolntsev added this to the 4.42.0 milestone Mar 9, 2026
@selenium-ci selenium-ci added C-java Java Bindings B-build Includes scripting, bazel and CI integrations labels Mar 9, 2026
@asolntsev asolntsev changed the title Nullability [java] specify nullability in other java packages Mar 9, 2026
@qodo-code-review

Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Add JSpecify nullability annotations to events, interactions, and logging packages

✨ Enhancement 📦 Other

Grey Divider

Walkthroughs

Description
• Add JSpecify @NullMarked annotations to events, interactions, and logging packages
• Remove class-level @NullMarked annotations, replace with package-level declarations
• Improve nullability handling in UnboundZmqEventBus by making sockets final and initializing in
  constructor
• Update Encodable interface to use @Nullable Object in return types for better null-safety
• Add @NullMarked method annotations to logging and remote driver implementations

Grey Divider

File Changes

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

Create package-info with NullMarked annotation

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


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

Create package-info with NullMarked annotation

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


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

Create package-info with NullMarked annotation

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


View more (32)
4. java/src/org/openqa/selenium/events/zeromq/UnboundZmqEventBus.java 🐞 Bug fix +24/-24

Make socket fields final and initialize in constructor

java/src/org/openqa/selenium/events/zeromq/UnboundZmqEventBus.java


5. java/src/org/openqa/selenium/events/zeromq/ZeroMqEventBus.java ✨ Enhancement +1/-0

Add DataFlowIssue suppression annotation

java/src/org/openqa/selenium/events/zeromq/ZeroMqEventBus.java


6. java/src/org/openqa/selenium/interactions/package-info.java ✨ Enhancement +21/-0

Create package-info with NullMarked annotation

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


7. java/src/org/openqa/selenium/interactions/Actions.java ✨ Enhancement +2/-6

Remove class-level NullMarked, make actionDuration final

java/src/org/openqa/selenium/interactions/Actions.java


8. java/src/org/openqa/selenium/interactions/CompositeAction.java ✨ Enhancement +0/-2

Remove class-level NullMarked annotation

java/src/org/openqa/selenium/interactions/CompositeAction.java


9. java/src/org/openqa/selenium/interactions/Coordinates.java ✨ Enhancement +0/-2

Remove class-level NullMarked annotation

java/src/org/openqa/selenium/interactions/Coordinates.java


10. java/src/org/openqa/selenium/interactions/Encodable.java ✨ Enhancement +2/-3

Update return type to use Nullable Object

java/src/org/openqa/selenium/interactions/Encodable.java


11. java/src/org/openqa/selenium/interactions/InputSource.java ✨ Enhancement +0/-3

Remove class-level NullMarked annotation

java/src/org/openqa/selenium/interactions/InputSource.java


12. java/src/org/openqa/selenium/interactions/Interaction.java ✨ Enhancement +0/-3

Remove class-level NullMarked annotation

java/src/org/openqa/selenium/interactions/Interaction.java


13. java/src/org/openqa/selenium/interactions/Interactive.java ✨ Enhancement +0/-2

Remove class-level NullMarked annotation

java/src/org/openqa/selenium/interactions/Interactive.java


14. java/src/org/openqa/selenium/interactions/KeyInput.java ✨ Enhancement +2/-4

Remove class-level NullMarked, update encode return type

java/src/org/openqa/selenium/interactions/KeyInput.java


15. java/src/org/openqa/selenium/interactions/Locatable.java ✨ Enhancement +0/-3

Remove class-level NullMarked annotation

java/src/org/openqa/selenium/interactions/Locatable.java


16. java/src/org/openqa/selenium/interactions/MoveTargetOutOfBoundsException.java ✨ Enhancement +0/-2

Remove class-level NullMarked annotation

java/src/org/openqa/selenium/interactions/MoveTargetOutOfBoundsException.java


17. java/src/org/openqa/selenium/interactions/Pause.java ✨ Enhancement +0/-2

Remove class-level NullMarked annotation

java/src/org/openqa/selenium/interactions/Pause.java


18. java/src/org/openqa/selenium/interactions/PointerInput.java ✨ Enhancement +2/-4

Remove class-level NullMarked, update encode return type

java/src/org/openqa/selenium/interactions/PointerInput.java


19. java/src/org/openqa/selenium/interactions/Sequence.java ✨ Enhancement +6/-7

Remove class-level NullMarked, update encode return types

java/src/org/openqa/selenium/interactions/Sequence.java


20. java/src/org/openqa/selenium/interactions/SourceType.java ✨ Enhancement +0/-2

Remove class-level NullMarked annotation

java/src/org/openqa/selenium/interactions/SourceType.java


21. java/src/org/openqa/selenium/interactions/WheelInput.java ✨ Enhancement +2/-4

Remove class-level NullMarked, update encode return type

java/src/org/openqa/selenium/interactions/WheelInput.java


22. java/src/org/openqa/selenium/logging/package-info.java ✨ Enhancement +21/-0

Create package-info with NullMarked annotation

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


23. java/src/org/openqa/selenium/logging/profiler/package-info.java ✨ Enhancement +21/-0

Create package-info with NullMarked annotation

java/src/org/openqa/selenium/logging/profiler/package-info.java


24. java/src/org/openqa/selenium/logging/LocalLogs.java ✨ Enhancement +3/-0

Add NullMarked annotations to abstract methods

java/src/org/openqa/selenium/logging/LocalLogs.java


25. java/src/org/openqa/selenium/logging/CompositeLocalLogs.java ✨ Enhancement +2/-0

Add NullMarked annotation to get method

java/src/org/openqa/selenium/logging/CompositeLocalLogs.java


26. java/src/org/openqa/selenium/logging/HandlerBasedLocalLogs.java ✨ Enhancement +2/-0

Add NullMarked annotation to get method

java/src/org/openqa/selenium/logging/HandlerBasedLocalLogs.java


27. java/src/org/openqa/selenium/logging/StoringLocalLogs.java ✨ Enhancement +2/-0

Add NullMarked annotation to get method

java/src/org/openqa/selenium/logging/StoringLocalLogs.java


28. java/src/org/openqa/selenium/logging/SessionLogs.java ✨ Enhancement +2/-1

Add Nullable annotation to getLogs parameter

java/src/org/openqa/selenium/logging/SessionLogs.java


29. java/src/org/openqa/selenium/chromium/ChromiumDriver.java ✨ Enhancement +2/-0

Add NullMarked annotation to onLogEvent method

java/src/org/openqa/selenium/chromium/ChromiumDriver.java


30. java/src/org/openqa/selenium/remote/AddHasLogEvents.java ✨ Enhancement +2/-0

Add NullMarked annotation to onLogEvent method

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


31. java/src/org/openqa/selenium/remote/RemoteLogs.java ✨ Enhancement +2/-0

Add NullMarked annotation to get method

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


32. java/src/org/openqa/selenium/remote/RemoteWebDriver.java ✨ Enhancement +2/-0

Add NullMarked annotation to perform method

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


33. java/src/org/openqa/selenium/events/BUILD.bazel ⚙️ Configuration changes +2/-1

Add jspecify dependency to events library

java/src/org/openqa/selenium/events/BUILD.bazel


34. java/src/org/openqa/selenium/events/local/BUILD.bazel ⚙️ Configuration changes +1/-0

Add jspecify dependency to local events library

java/src/org/openqa/selenium/events/local/BUILD.bazel


35. java/src/org/openqa/selenium/events/zeromq/BUILD.bazel ⚙️ Configuration changes +1/-0

Add jspecify dependency to zeromq events library

java/src/org/openqa/selenium/events/zeromq/BUILD.bazel


Grey Divider

Qodo Logo

@qodo-code-review

qodo-code-review Bot commented Mar 9, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. RejectedEvent may be null 🐞 Bug ✓ Correctness
Description
ZeroMqEventBus.RejectedEvent.fromJson can construct a RejectedEvent with null name/data when the
JSON omits those fields, but the class lives in an @NullMarked package so those fields/getters are
treated as non-null. This can cause runtime NPEs in rejected-event handlers and can also trigger
nullness-check failures in builds running NullAway.
Code

java/src/org/openqa/selenium/events/zeromq/ZeroMqEventBus.java[R149-152]

+    @SuppressWarnings("DataFlowIssue")
    private static RejectedEvent fromJson(JsonInput input) {
      EventName name = null;
      Object data = null;
Evidence
The PR marks the entire org.openqa.selenium.events.zeromq package as @NullMarked, making unannotated
reference types non-null by default; however fromJson initializes name/data to null and returns a
RejectedEvent built from those possibly-null values, while the fields/getters remain unannotated
(therefore non-null under @NullMarked). The repo’s Bazel rules enable NullAway for
org.openqa.selenium, so this inconsistency is likely to be caught by nullness tooling and is also a
real runtime risk if malformed JSON is received.

java/src/org/openqa/selenium/events/zeromq/package-info.java[18-21]
java/src/org/openqa/selenium/events/zeromq/ZeroMqEventBus.java[140-173]
java/src/org/openqa/selenium/events/zeromq/ZeroMqEventBus.java[175-181]
java/private/java_library.bzl[16-35]

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

## Issue description
`org.openqa.selenium.events.zeromq` is now `@NullMarked`, but `ZeroMqEventBus.RejectedEvent.fromJson` can still build a `RejectedEvent` with `null` `name`/`data` when the JSON payload is missing fields.

## Issue Context
Because the package is `@NullMarked`, `RejectedEvent.name`/`data` and their getters are implicitly non-null. Returning instances with nulls violates that contract and risks runtime NPEs.

## Fix Focus Areas
- java/src/org/openqa/selenium/events/zeromq/ZeroMqEventBus.java[140-173]
- java/src/org/openqa/selenium/events/zeromq/ZeroMqEventBus.java[175-181]

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



Remediation recommended

2. Nullable prefs not annotated 🐞 Bug ⛯ Reliability
Description
LoggingPreferences.addPreferences explicitly accepts null (it checks prefs == null) but
org.openqa.selenium.logging is now @NullMarked, so the parameter is non-null by default. This makes
the nullness contract incorrect and can cause false-positive nullness errors at call sites (or force
suppressions) despite the method safely handling null.
Code

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

+@NullMarked
+package org.openqa.selenium.logging;
+
+import org.jspecify.annotations.NullMarked;
Evidence
The PR makes the logging package @NullMarked, which implies non-null parameters by default; however
addPreferences still contains a null-guard for its parameter, indicating null is a supported input.
With NullAway enabled for org.openqa.selenium packages, keeping the parameter implicitly non-null
misrepresents the API’s behavior for nullness tooling.

java/src/org/openqa/selenium/logging/package-info.java[18-21]
java/src/org/openqa/selenium/logging/LoggingPreferences.java[71-85]
java/private/java_library.bzl[16-35]

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

## Issue description
`org.openqa.selenium.logging` is now `@NullMarked`, but `LoggingPreferences.addPreferences` still accepts `null` without marking the parameter `@Nullable`.

## Issue Context
The method has an explicit `prefs == null` guard, so null is an allowed input and should be reflected in the signature for nullness tooling.

## Fix Focus Areas
- java/src/org/openqa/selenium/logging/LoggingPreferences.java[18-28]
- java/src/org/openqa/selenium/logging/LoggingPreferences.java[71-85]

ⓘ 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 removed the B-build Includes scripting, bazel and CI integrations label Mar 9, 2026
@asolntsev
asolntsev marked this pull request as draft March 9, 2026 17:37
Comment thread java/src/org/openqa/selenium/events/zeromq/ZeroMqEventBus.java
@asolntsev
asolntsev marked this pull request as ready for review March 12, 2026 22:32
@asolntsev
asolntsev merged commit 1173aee into SeleniumHQ:trunk Mar 12, 2026
43 of 44 checks passed
@asolntsev
asolntsev deleted the nullability branch March 12, 2026 22:33
@qodo-code-review

Copy link
Copy Markdown
Contributor

Review Summary by Qodo

✨ Enhancement 🧪 Tests

Grey Divider

Walkthroughs

Description
• Add JSpecify nullability annotations across multiple Java packages
• Create package-info.java files with @NullMarked for 8 packages
• Refactor code to use Require utility for validation
• Improve Lazy class with exception handling and thread safety
• Update BUILD.bazel files to include jspecify dependency

Grey Divider

File Changes

1. java/src/org/openqa/selenium/Architecture.java ✨ Enhancement +2/-1

Add nullability annotation to parameter

java/src/org/openqa/selenium/Architecture.java


2. java/src/org/openqa/selenium/BuildInfo.java ✨ Enhancement +10/-5

Improve error handling and logging

java/src/org/openqa/selenium/BuildInfo.java


3. java/src/org/openqa/selenium/Cookie.java ✨ Enhancement +4/-4

Add nullability and use Require validation

java/src/org/openqa/selenium/Cookie.java


View more (63)
4. java/src/org/openqa/selenium/DeviceRotation.java ✨ Enhancement +3/-1

Add nullability and use Require validation

java/src/org/openqa/selenium/DeviceRotation.java


5. java/src/org/openqa/selenium/InvalidCookieDomainException.java Cleanup +3/-5

Remove unnecessary nullability annotations

java/src/org/openqa/selenium/InvalidCookieDomainException.java


6. java/src/org/openqa/selenium/Platform.java Cleanup +23/-23

Remove nullability annotations from methods

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


7. java/src/org/openqa/selenium/SharedCapabilitiesMethods.java ✨ Enhancement +2/-1

Add nullability annotation to parameter

java/src/org/openqa/selenium/SharedCapabilitiesMethods.java


8. java/src/org/openqa/selenium/UnableToSetCookieException.java Cleanup +3/-5

Remove unnecessary nullability annotations

java/src/org/openqa/selenium/UnableToSetCookieException.java


9. java/src/org/openqa/selenium/UnhandledAlertException.java ✨ Enhancement +6/-4

Add nullability annotations to fields and methods

java/src/org/openqa/selenium/UnhandledAlertException.java


10. java/src/org/openqa/selenium/chromium/ChromiumDriver.java ✨ Enhancement +2/-0

Add NullMarked annotation to method

java/src/org/openqa/selenium/chromium/ChromiumDriver.java


11. java/src/org/openqa/selenium/concurrent/Lazy.java ✨ Enhancement +21/-6

Refactor with custom Supplier interface and exception handling

java/src/org/openqa/selenium/concurrent/Lazy.java


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

Create package-info with NullMarked annotation

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


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

Create package-info with NullMarked annotation

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


14. java/src/org/openqa/selenium/events/zeromq/UnboundZmqEventBus.java ✨ Enhancement +24/-24

Make socket fields final and improve initialization

java/src/org/openqa/selenium/events/zeromq/UnboundZmqEventBus.java


15. java/src/org/openqa/selenium/events/zeromq/ZeroMqEventBus.java ✨ Enhancement +1/-0

Add SuppressWarnings annotation

java/src/org/openqa/selenium/events/zeromq/ZeroMqEventBus.java


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

Create package-info with NullMarked annotation

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


17. java/src/org/openqa/selenium/interactions/Actions.java ✨ Enhancement +2/-6

Remove NullMarked and use Require validation

java/src/org/openqa/selenium/interactions/Actions.java


18. java/src/org/openqa/selenium/interactions/CompositeAction.java Cleanup +0/-2

Remove NullMarked annotation

java/src/org/openqa/selenium/interactions/CompositeAction.java


19. java/src/org/openqa/selenium/interactions/Coordinates.java Cleanup +0/-2

Remove NullMarked annotation

java/src/org/openqa/selenium/interactions/Coordinates.java


20. java/src/org/openqa/selenium/interactions/Encodable.java ✨ Enhancement +2/-3

Replace NullMarked with Nullable annotation

java/src/org/openqa/selenium/interactions/Encodable.java


21. java/src/org/openqa/selenium/interactions/InputSource.java Cleanup +0/-3

Remove NullMarked annotation

java/src/org/openqa/selenium/interactions/InputSource.java


22. java/src/org/openqa/selenium/interactions/Interaction.java Cleanup +0/-3

Remove NullMarked annotation

java/src/org/openqa/selenium/interactions/Interaction.java


23. java/src/org/openqa/selenium/interactions/Interactive.java Cleanup +0/-2

Remove NullMarked annotation

java/src/org/openqa/selenium/interactions/Interactive.java


24. java/src/org/openqa/selenium/interactions/KeyInput.java ✨ Enhancement +2/-4

Remove NullMarked and add Nullable to return type

java/src/org/openqa/selenium/interactions/KeyInput.java


25. java/src/org/openqa/selenium/interactions/Locatable.java Cleanup +0/-3

Remove NullMarked annotation

java/src/org/openqa/selenium/interactions/Locatable.java


26. java/src/org/openqa/selenium/interactions/MoveTargetOutOfBoundsException.java Cleanup +0/-2

Remove NullMarked annotation

java/src/org/openqa/selenium/interactions/MoveTargetOutOfBoundsException.java


27. java/src/org/openqa/selenium/interactions/Pause.java Cleanup +0/-2

Remove NullMarked annotation

java/src/org/openqa/selenium/interactions/Pause.java


28. java/src/org/openqa/selenium/interactions/PointerInput.java ✨ Enhancement +2/-4

Remove NullMarked and add Nullable to return type

java/src/org/openqa/selenium/interactions/PointerInput.java


29. java/src/org/openqa/selenium/interactions/Sequence.java ✨ Enhancement +6/-7

Remove NullMarked and add Nullable to return types

java/src/org/openqa/selenium/interactions/Sequence.java


30. java/src/org/openqa/selenium/interactions/SourceType.java Cleanup +0/-2

Remove NullMarked annotation

java/src/org/openqa/selenium/interactions/SourceType.java


31. java/src/org/openqa/selenium/interactions/WheelInput.java ✨ Enhancement +2/-4

Remove NullMarked and add Nullable to return type

java/src/org/openqa/selenium/interactions/WheelInput.java


32. java/src/org/openqa/selenium/interactions/package-info.java ✨ Enhancement +21/-0

Create package-info with NullMarked annotation

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


33. java/src/org/openqa/selenium/internal/Require.java ✨ Enhancement +8/-0

Add nonEmpty validation method

java/src/org/openqa/selenium/internal/Require.java


34. java/src/org/openqa/selenium/logging/CompositeLocalLogs.java ✨ Enhancement +2/-0

Add NullMarked annotation to method

java/src/org/openqa/selenium/logging/CompositeLocalLogs.java


35. java/src/org/openqa/selenium/logging/HandlerBasedLocalLogs.java ✨ Enhancement +2/-0

Add NullMarked annotation to method

java/src/org/openqa/selenium/logging/HandlerBasedLocalLogs.java


36. java/src/org/openqa/selenium/logging/LocalLogs.java ✨ Enhancement +3/-0

Add NullMarked annotations to methods

java/src/org/openqa/selenium/logging/LocalLogs.java


37. java/src/org/openqa/selenium/logging/SessionLogs.java ✨ Enhancement +2/-1

Add Nullable annotation to parameter

java/src/org/openqa/selenium/logging/SessionLogs.java


38. java/src/org/openqa/selenium/logging/StoringLocalLogs.java ✨ Enhancement +2/-0

Add NullMarked annotation to method

java/src/org/openqa/selenium/logging/StoringLocalLogs.java


39. java/src/org/openqa/selenium/logging/package-info.java ✨ Enhancement +21/-0

Create package-info with NullMarked annotation

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


40. java/src/org/openqa/selenium/logging/profiler/package-info.java ✨ Enhancement +21/-0

Create package-info with NullMarked annotation

java/src/org/openqa/selenium/logging/profiler/package-info.java


41. java/src/org/openqa/selenium/netty/server/NettyServer.java ✨ Enhancement +5/-4

Add nullability annotations to fields

java/src/org/openqa/selenium/netty/server/NettyServer.java


42. java/src/org/openqa/selenium/netty/server/RequestConverter.java ✨ Enhancement +4/-2

Add nullability annotations to fields and methods

java/src/org/openqa/selenium/netty/server/RequestConverter.java


43. java/src/org/openqa/selenium/netty/server/SeleniumHttpInitializer.java ✨ Enhancement +5/-4

Add nullability annotations to fields and parameters

java/src/org/openqa/selenium/netty/server/SeleniumHttpInitializer.java


44. java/src/org/openqa/selenium/netty/server/TcpUpgradeTunnelHandler.java ✨ Enhancement +11/-18

Refactor SSL context initialization with Lazy

java/src/org/openqa/selenium/netty/server/TcpUpgradeTunnelHandler.java


45. java/src/org/openqa/selenium/netty/server/WebSocketUpgradeHandler.java ✨ Enhancement +2/-1

Add nullability annotation to field

java/src/org/openqa/selenium/netty/server/WebSocketUpgradeHandler.java


46. java/src/org/openqa/selenium/netty/server/package-info.java ✨ Enhancement +21/-0

Create package-info with NullMarked annotation

java/src/org/openqa/selenium/netty/server/package-info.java


47. java/src/org/openqa/selenium/redis/GridRedisClient.java ✨ Enhancement +5/-2

Add nullability annotation and optimize stream operations

java/src/org/openqa/selenium/redis/GridRedisClient.java


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

Create package-info with NullMarked annotation

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


49. java/src/org/openqa/selenium/remote/AddHasLogEvents.java ✨ Enhancement +2/-0

Add NullMarked annotation to method

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


50. java/src/org/openqa/selenium/remote/RemoteLogs.java ✨ Enhancement +2/-0

Add NullMarked annotation to method

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


51. java/src/org/openqa/selenium/remote/RemoteWebDriver.java ✨ Enhancement +7/-0

Add NullMarked annotations to multiple methods

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


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

Create package-info with NullMarked annotation

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


53. java/src/org/openqa/selenium/virtualauthenticator/Credential.java ✨ Enhancement +1/-3

Remove NullMarked and add Nullable to return type

java/src/org/openqa/selenium/virtualauthenticator/Credential.java


54. java/src/org/openqa/selenium/virtualauthenticator/HasVirtualAuthenticator.java Cleanup +0/-3

Remove NullMarked annotation

java/src/org/openqa/selenium/virtualauthenticator/HasVirtualAuthenticator.java


55. java/src/org/openqa/selenium/virtualauthenticator/VirtualAuthenticator.java Cleanup +0/-2

Remove NullMarked annotation

java/src/org/openqa/selenium/virtualauthenticator/VirtualAuthenticator.java


56. java/src/org/openqa/selenium/virtualauthenticator/VirtualAuthenticatorOptions.java Cleanup +0/-2

Remove NullMarked annotation

java/src/org/openqa/selenium/virtualauthenticator/VirtualAuthenticatorOptions.java


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

Create package-info with NullMarked annotation

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


58. java/test/org/openqa/selenium/StubDriver.java 🧪 Tests +10/-2

Add nullability annotations to test class

java/test/org/openqa/selenium/StubDriver.java


59. java/test/org/openqa/selenium/WrappedWebElement.java 🧪 Tests +2/-0

Add NullMarked annotation to test class

java/test/org/openqa/selenium/WrappedWebElement.java


60. java/src/org/openqa/selenium/events/BUILD.bazel ⚙️ Configuration changes +2/-1

Add jspecify dependency

java/src/org/openqa/selenium/events/BUILD.bazel


61. java/src/org/openqa/selenium/events/local/BUILD.bazel ⚙️ Configuration changes +1/-0

Add jspecify dependency

java/src/org/openqa/selenium/events/local/BUILD.bazel


62. java/src/org/openqa/selenium/events/zeromq/BUILD.bazel ⚙️ Configuration changes +1/-0

Add jspecify dependency

java/src/org/openqa/selenium/events/zeromq/BUILD.bazel


63. java/src/org/openqa/selenium/netty/server/BUILD.bazel ⚙️ Configuration changes +1/-0

Add jspecify dependency

java/src/org/openqa/selenium/netty/server/BUILD.bazel


64. java/src/org/openqa/selenium/redis/BUILD.bazel ⚙️ Configuration changes +1/-0

Add jspecify dependency

java/src/org/openqa/selenium/redis/BUILD.bazel


65. java/src/org/openqa/selenium/status/BUILD.bazel ⚙️ Configuration changes +4/-0

Add jspecify dependency

java/src/org/openqa/selenium/status/BUILD.bazel


66. java/test/org/openqa/selenium/BUILD.bazel ⚙️ Configuration changes +3/-0

Add jspecify dependency to test targets

java/test/org/openqa/selenium/BUILD.bazel


Grey Divider

Qodo Logo

@qodo-code-review

qodo-code-review Bot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (2) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Lazy now final, new Supplier 📘 Rule violation ✓ Correctness ⭐ New
Description
Lazy was made final and its factory now accepts a new nested Lazy.Supplier instead of
java.util.function.Supplier, breaking source compatibility for callers that subclass Lazy or
pass a java.util.function.Supplier variable. This violates the requirement to maintain backwards
compatible public APIs/ABIs for upgrades.
Code

java/src/org/openqa/selenium/concurrent/Lazy.java[R25-50]

+public final class Lazy<T> {

-  @Nullable private volatile T value;
+  private final Object lock = new Object();
+  private volatile @Nullable T value;
  private final Supplier<T> supplier;

  private Lazy(Supplier<T> supplier) {
    this.supplier = supplier;
  }

  public Optional<T> getIfInitialized() {
-    return Optional.ofNullable(value);
+    return value == null ? Optional.empty() : Optional.ofNullable(value);
  }

  public T get() {
    if (value == null) {
-      synchronized (this) {
+      synchronized (lock) {
        if (value == null) {
-          value = supplier.get();
+          try {
+            value = supplier.get();
+          } catch (Exception e) {
+            throw new InitializationException(e);
+          }
        }
      }
    }
Evidence
Compliance ID 2 requires public API/ABI compatibility, but the PR changes Lazy to final and
changes lazy(...) to take a different functional interface type (Lazy.Supplier) with different
throws contract, which can break existing callers at compile time.

AGENTS.md
java/src/org/openqa/selenium/concurrent/Lazy.java[25-61]

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

## Issue description
`org.openqa.selenium.concurrent.Lazy` introduces breaking API changes by becoming `final` and by changing its public factory parameter type from `java.util.function.Supplier` to a new nested `Lazy.Supplier`.

## Issue Context
This is a public type under `org.openqa.selenium.concurrent` and can be used by external callers. Callers that subclass `Lazy` or that store suppliers in `java.util.function.Supplier&lt;T&gt;` variables may fail to compile after upgrading.

## Fix Focus Areas
- java/src/org/openqa/selenium/concurrent/Lazy.java[25-61]

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


2. RejectedEvent may be null 🐞 Bug ✓ Correctness
Description
ZeroMqEventBus.RejectedEvent.fromJson can construct a RejectedEvent with null name/data when the
JSON omits those fields, but the class lives in an @NullMarked package so those fields/getters are
treated as non-null. This can cause runtime NPEs in rejected-event handlers and can also trigger
nullness-check failures in builds running NullAway.
Code

java/src/org/openqa/selenium/events/zeromq/ZeroMqEventBus.java[R149-152]

+    @SuppressWarnings("DataFlowIssue")
   private static RejectedEvent fromJson(JsonInput input) {
     EventName name = null;
     Object data = null;
Evidence
The PR marks the entire org.openqa.selenium.events.zeromq package as @NullMarked, making unannotated
reference types non-null by default; however fromJson initializes name/data to null and returns a
RejectedEvent built from those possibly-null values, while the fields/getters remain unannotated
(therefore non-null under @NullMarked). The repo’s Bazel rules enable NullAway for
org.openqa.selenium, so this inconsistency is likely to be caught by nullness tooling and is also a
real runtime risk if malformed JSON is received.

java/src/org/openqa/selenium/events/zeromq/package-info.java[18-21]
java/src/org/openqa/selenium/events/zeromq/ZeroMqEventBus.java[140-173]
java/src/org/openqa/selenium/events/zeromq/ZeroMqEventBus.java[175-181]
java/private/java_library.bzl[16-35]

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

## Issue description
`org.openqa.selenium.events.zeromq` is now `@NullMarked`, but `ZeroMqEventBus.RejectedEvent.fromJson` can still build a `RejectedEvent` with `null` `name`/`data` when the JSON payload is missing fields.
## Issue Context
Because the package is `@NullMarked`, `RejectedEvent.name`/`data` and their getters are implicitly non-null. Returning instances with nulls violates that contract and risks runtime NPEs.
## Fix Focus Areas
- java/src/org/openqa/selenium/events/zeromq/ZeroMqEventBus.java[140-173]
- java/src/org/openqa/selenium/events/zeromq/ZeroMqEventBus.java[175-181]

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



Remediation recommended

3. Lazy.get wraps supplier exceptions 📘 Rule violation ⛯ Reliability ⭐ New
Description
Lazy.get() now catches any Exception from the supplier and wraps it in
InitializationException, changing the exception type/behavior observed by callers. This is a
behavior change that should be covered by focused unit tests to prevent regressions.
Code

java/src/org/openqa/selenium/concurrent/Lazy.java[R39-47]

  public T get() {
    if (value == null) {
-      synchronized (this) {
+      synchronized (lock) {
        if (value == null) {
-          value = supplier.get();
+          try {
+            value = supplier.get();
+          } catch (Exception e) {
+            throw new InitializationException(e);
+          }
Evidence
Compliance ID 4 expects tests for behavior changes when feasible; the new try/catch changes runtime
behavior by wrapping supplier failures, but the PR diff does not include any new/updated unit tests
covering this new behavior.

AGENTS.md
java/src/org/openqa/selenium/concurrent/Lazy.java[39-47]

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

## Issue description
`Lazy.get()` now wraps supplier exceptions in `InitializationException`, but there is no accompanying unit test coverage in the PR diff.

## Issue Context
This behavior impacts callers who rely on the exception type thrown during lazy initialization and should be locked down with fast unit tests.

## Fix Focus Areas
- java/src/org/openqa/selenium/concurrent/Lazy.java[39-67]

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


4. Nullable prefs not annotated 🐞 Bug ⛯ Reliability
Description
LoggingPreferences.addPreferences explicitly accepts null (it checks prefs == null) but
org.openqa.selenium.logging is now @NullMarked, so the parameter is non-null by default. This makes
the nullness contract incorrect and can cause false-positive nullness errors at call sites (or force
suppressions) despite the method safely handling null.
Code

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

+@NullMarked
+package org.openqa.selenium.logging;
+
+import org.jspecify.annotations.NullMarked;
Evidence
The PR makes the logging package @NullMarked, which implies non-null parameters by default; however
addPreferences still contains a null-guard for its parameter, indicating null is a supported input.
With NullAway enabled for org.openqa.selenium packages, keeping the parameter implicitly non-null
misrepresents the API’s behavior for nullness tooling.

java/src/org/openqa/selenium/logging/package-info.java[18-21]
java/src/org/openqa/selenium/logging/LoggingPreferences.java[71-85]
java/private/java_library.bzl[16-35]

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

## Issue description
`org.openqa.selenium.logging` is now `@NullMarked`, but `LoggingPreferences.addPreferences` still accepts `null` without marking the parameter `@Nullable`.
## Issue Context
The method has an explicit `prefs == null` guard, so null is an allowed input and should be reflected in the signature for nullness tooling.
## Fix Focus Areas
- java/src/org/openqa/selenium/logging/LoggingPreferences.java[18-28]
- java/src/org/openqa/selenium/logging/LoggingPreferences.java[71-85]

ⓘ 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

Comment on lines +25 to 50
public final class Lazy<T> {

@Nullable private volatile T value;
private final Object lock = new Object();
private volatile @Nullable T value;
private final Supplier<T> supplier;

private Lazy(Supplier<T> supplier) {
this.supplier = supplier;
}

public Optional<T> getIfInitialized() {
return Optional.ofNullable(value);
return value == null ? Optional.empty() : Optional.ofNullable(value);
}

public T get() {
if (value == null) {
synchronized (this) {
synchronized (lock) {
if (value == null) {
value = supplier.get();
try {
value = supplier.get();
} catch (Exception e) {
throw new InitializationException(e);
}
}
}
}

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

1. lazy now final, new supplier 📘 Rule violation ✓ Correctness

Lazy was made final and its factory now accepts a new nested Lazy.Supplier instead of
java.util.function.Supplier, breaking source compatibility for callers that subclass Lazy or
pass a java.util.function.Supplier variable. This violates the requirement to maintain backwards
compatible public APIs/ABIs for upgrades.
Agent Prompt
## Issue description
`org.openqa.selenium.concurrent.Lazy` introduces breaking API changes by becoming `final` and by changing its public factory parameter type from `java.util.function.Supplier` to a new nested `Lazy.Supplier`.

## Issue Context
This is a public type under `org.openqa.selenium.concurrent` and can be used by external callers. Callers that subclass `Lazy` or that store suppliers in `java.util.function.Supplier<T>` variables may fail to compile after upgrading.

## Fix Focus Areas
- java/src/org/openqa/selenium/concurrent/Lazy.java[25-61]

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

@VietND96 VietND96 mentioned this pull request Mar 17, 2026
krishnamohan-kothapalli pushed a commit to krishnamohan-kothapalli/selenium that referenced this pull request Mar 18, 2026
* specify nullability in package `org.openqa.selenium.events`
* specify nullability in package `org.openqa.selenium.interactions`
* specify nullability in package `org.openqa.selenium.logging`
* specify nullability in package `org.openqa.selenium.netty.server`
* specify nullability in package `org.openqa.selenium.redis`
* specify nullability in package `org.openqa.selenium.status`
* specify nullability in package `org.openqa.selenium.virtualauthenticator`
* specify nullability in package `org.openqa.selenium`

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

Labels

C-java Java Bindings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants