[java] JSpecify annotations for `org.openqa.selenium.net` by mk868 · Pull Request #16463 · SeleniumHQ/selenium
User description
🔗 Related Issues
Related #14291
💥 What does this PR do?
JSpecify annotations added to the:
org.openqa.selenium.net.LinuxEphemeralPortRangeDetectororg.openqa.selenium.net.NetworkUtilsorg.openqa.selenium.net.PortProberorg.openqa.selenium.net.UrlCheckerorg.openqa.selenium.net.Urls
🔧 Implementation Notes
💡 Additional Considerations
🔄 Types of changes
- New feature (non-breaking change which adds functionality and tests!)
PR Type
Enhancement
Description
-
Add JSpecify @NullMarked annotations to five net package classes
-
Mark nullable fields and return types with @nullable annotation
-
Add null-safety checks using Require.nonNull() for guaranteed non-null returns
-
Improve type safety and null-handling in NetworkUtils class
Diagram Walkthrough
flowchart LR
A["Five net package classes"] -->|Add @NullMarked| B["Class-level null contracts"]
A -->|Mark nullable fields| C["@Nullable annotations"]
A -->|Add null checks| D["Require.nonNull() calls"]
B --> E["Improved type safety"]
C --> E
D --> E
File Walkthrough
| Relevant files | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Enhancement |
|
PR Compliance Guide 🔍
Below is a summary of compliance checks for this PR:
| Security Compliance | ||||||||||
| ⚪ | Nullability contract changeDescription: The new nullable return in obtainLoopbackIp4Address() may return null where callers Referred Codepublic @Nullable String obtainLoopbackIp4Address() { final NetworkInterface networkInterface = getLoopBackAndIp4Only(); if (networkInterface != null) { InetAddress loopback = networkInterface.getIp4LoopbackOnly(); if (loopback != null) { return loopback.getHostName(); } } final String ipOfIp4LoopBack = getIpOfLoopBackIp4(); if (ipOfIp4LoopBack != null) { return ipOfIp4LoopBack; | |||||||||
Unexpected runtime throwDescription: getHostname() and getHostAddress() now throw at runtime via Require.nonNull if Referred Codepublic String getHostname() { determineHostnameAndAddress(); return Require.nonNull("Hostname", hostname); } public String getHostAddress() { determineHostnameAndAddress(); return Require.nonNull("Address", address); } | ||||||||||
| Ticket Compliance | ||||||||||
| 🟡 |
🎫 #14291
| |||||||||
| Codebase Duplication Compliance | ||||||||||
| ⚪ | Codebase context is not definedFollow the guide to enable codebase context checks. | |||||||||
| Custom Compliance | ||||||||||
| ⚪ | No custom compliance providedFollow the guide to enable custom compliance check. | |||||||||
| ||||||||||
Compliance status legend
🟢 - Fully Compliant🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label
PR Code Suggestions ✨
Explore these optional code suggestions:
| Category | Suggestion | Impact |
| High-level |
Re-evaluate the nullability contract changeThe PR introduces a breaking change by making Examples:java/src/org/openqa/selenium/net/NetworkUtils.java [60-70]public String getHostname() { determineHostnameAndAddress(); return Require.nonNull("Hostname", hostname); } public String getHostAddress() { determineHostnameAndAddress(); return Require.nonNull("Address", address); ... (clipped 1 lines) Solution Walkthrough:Before:// in NetworkUtils.java @NullMarked public class NetworkUtils { private volatile @Nullable String hostname; private volatile @Nullable String address; public String getHostname() { determineHostnameAndAddress(); return Require.nonNull("Hostname", hostname); // Throws if hostname is null } public String getHostAddress() { determineHostnameAndAddress(); return Require.nonNull("Address", address); // Throws if address is null } } After:// in NetworkUtils.java @NullMarked public class NetworkUtils { private volatile @Nullable String hostname; private volatile @Nullable String address; public @Nullable String getHostname() { determineHostnameAndAddress(); return hostname; // Can return null } public @Nullable String getHostAddress() { determineHostnameAndAddress(); return address; // Can return null } } Suggestion importance[1-10]: 9__ Why: The suggestion correctly identifies a breaking change in the public API contract of | High |
| Possible issue |
Prevent potential NullPointerException on addressAdd a null check for java/src/org/openqa/selenium/net/NetworkUtils.java [88-96] public @Nullable String getNonLoopbackAddressOfThisMachine() {
InetAddress ip4NonLoopbackAddressOfThisMachine = getIp4NonLoopbackAddressOfThisMachine();
if (!Objects.equals(
cachedIp4NonLoopbackAddressOfThisMachine, ip4NonLoopbackAddressOfThisMachine)) {
cachedIp4NonLoopbackAddressOfThisMachine = ip4NonLoopbackAddressOfThisMachine;
- cachedIp4NonLoopbackAddressHostName = ip4NonLoopbackAddressOfThisMachine.getHostAddress();
+ cachedIp4NonLoopbackAddressHostName =
+ ip4NonLoopbackAddressOfThisMachine == null
+ ? null
+ : ip4NonLoopbackAddressOfThisMachine.getHostAddress();
}
return cachedIp4NonLoopbackAddressHostName;
}
Suggestion importance[1-10]: 9__ Why: The suggestion correctly identifies a potential | High |
| ||
mk868
deleted the
jspecify-net
branch
This was referenced
Oct 25, 2025This was referenced
Dec 16, 2025This was referenced
Jan 19, 2026This was referenced
Feb 11, 2026This was referenced
Feb 20, 2026This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters