Skip to content

[java] specify nullability in other java packages#17194

Draft
asolntsev wants to merge 3 commits intoSeleniumHQ:trunkfrom
asolntsev:nullability
Draft

[java] specify nullability in other java packages#17194
asolntsev wants to merge 3 commits intoSeleniumHQ:trunkfrom
asolntsev:nullability

Conversation

@asolntsev
Copy link
Contributor

🔗 Related Issues

Partially implements #14291

💥 What does this PR do?

Adds JSpecify nullability annotations to packages

  • org.openqa.selenium.docker.*

🔄 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
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
Copy link
Contributor

qodo-code-review bot commented Mar 9, 2026

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 on lines +149 to 152
@SuppressWarnings("DataFlowIssue")
private static RejectedEvent fromJson(JsonInput input) {
EventName name = null;
Object data = null;
Copy link
Contributor

Choose a reason for hiding this comment

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

Action required

1. Rejectedevent may be null 🐞 Bug ✓ Correctness

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.
Agent Prompt
## 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

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