From 625b815a68ed0165635561175dced1964b1d7a97 Mon Sep 17 00:00:00 2001 From: Andrei Solntsev Date: Wed, 4 Mar 2026 11:23:46 +0200 Subject: [PATCH 1/2] remove occasionally copy-pasted javadoc --- .../openqa/selenium/edge/package-info.java | 29 ------------------- .../package-info.java | 29 ------------------- .../org/openqa/selenium/ie/package-info.java | 29 ------------------- .../openqa/selenium/print/package-info.java | 29 ------------------- .../openqa/selenium/safari/package-info.java | 29 ------------------- 5 files changed, 145 deletions(-) diff --git a/java/src/org/openqa/selenium/edge/package-info.java b/java/src/org/openqa/selenium/edge/package-info.java index 0ecb0d05d4dd3..5f1ac3fda669a 100644 --- a/java/src/org/openqa/selenium/edge/package-info.java +++ b/java/src/org/openqa/selenium/edge/package-info.java @@ -15,35 +15,6 @@ // specific language governing permissions and limitations // under the License. -/** - * Mechanisms to configure and run selenium via the command line. There are two key classes {@link - * org.openqa.selenium.cli.CliCommand} and {@link org.openqa.selenium.grid.config.HasRoles}. - * Ultimately, these are used to build a {@link org.openqa.selenium.grid.config.Config} instance, - * for which there are strongly-typed role-specific classes that use a {@code Config}, such as - * {@link org.openqa.selenium.grid.node.docker.DockerOptions}. - * - *

Assuming your {@code CliCommand} extends {@link org.openqa.selenium.grid.TemplateGridCommand}, - * the process for building the set of flags to use is: - * - *

    - *
  1. The default flags are added (these are {@link org.openqa.selenium.grid.server.HelpFlags} - * and {@link org.openqa.selenium.grid.config.ConfigFlags} - *
  2. {@link java.util.ServiceLoader} is used to find all implementations of {@link - * org.openqa.selenium.grid.config.HasRoles} where {@link - * org.openqa.selenium.grid.config.HasRoles#getRoles()} is contained within {@link - * org.openqa.selenium.cli.CliCommand#getConfigurableRoles()}. - *
  3. Finally all flags returned by {@link - * org.openqa.selenium.grid.TemplateGridCommand#getFlagObjects()} are added. - *
- * - *

The flags are then used by JCommander to parse the command arguments. Once that's done, the - * raw flags are converted to a {@link org.openqa.selenium.grid.config.Config} by combining all of - * the flag objects with system properties and environment variables. This implies that each flag - * object has annotated each field with {@link org.openqa.selenium.grid.config.ConfigValue}. - * - *

Ultimately, this means that flag objects have all (most?) fields annotated with JCommander's - * {@link com.beust.jcommander.Parameter} annotation as well as {@code ConfigValue}. - */ @NullMarked package org.openqa.selenium.edge; diff --git a/java/src/org/openqa/selenium/federatedcredentialmanagement/package-info.java b/java/src/org/openqa/selenium/federatedcredentialmanagement/package-info.java index 359e361a886f5..f2a1ac6f33779 100644 --- a/java/src/org/openqa/selenium/federatedcredentialmanagement/package-info.java +++ b/java/src/org/openqa/selenium/federatedcredentialmanagement/package-info.java @@ -15,35 +15,6 @@ // specific language governing permissions and limitations // under the License. -/** - * Mechanisms to configure and run selenium via the command line. There are two key classes {@link - * org.openqa.selenium.cli.CliCommand} and {@link org.openqa.selenium.grid.config.HasRoles}. - * Ultimately, these are used to build a {@link org.openqa.selenium.grid.config.Config} instance, - * for which there are strongly-typed role-specific classes that use a {@code Config}, such as - * {@link org.openqa.selenium.grid.node.docker.DockerOptions}. - * - *

Assuming your {@code CliCommand} extends {@link org.openqa.selenium.grid.TemplateGridCommand}, - * the process for building the set of flags to use is: - * - *

    - *
  1. The default flags are added (these are {@link org.openqa.selenium.grid.server.HelpFlags} - * and {@link org.openqa.selenium.grid.config.ConfigFlags} - *
  2. {@link java.util.ServiceLoader} is used to find all implementations of {@link - * org.openqa.selenium.grid.config.HasRoles} where {@link - * org.openqa.selenium.grid.config.HasRoles#getRoles()} is contained within {@link - * org.openqa.selenium.cli.CliCommand#getConfigurableRoles()}. - *
  3. Finally all flags returned by {@link - * org.openqa.selenium.grid.TemplateGridCommand#getFlagObjects()} are added. - *
- * - *

The flags are then used by JCommander to parse the command arguments. Once that's done, the - * raw flags are converted to a {@link org.openqa.selenium.grid.config.Config} by combining all of - * the flag objects with system properties and environment variables. This implies that each flag - * object has annotated each field with {@link org.openqa.selenium.grid.config.ConfigValue}. - * - *

Ultimately, this means that flag objects have all (most?) fields annotated with JCommander's - * {@link com.beust.jcommander.Parameter} annotation as well as {@code ConfigValue}. - */ @NullMarked package org.openqa.selenium.federatedcredentialmanagement; diff --git a/java/src/org/openqa/selenium/ie/package-info.java b/java/src/org/openqa/selenium/ie/package-info.java index e2d33d56dc710..e341052be7f8a 100644 --- a/java/src/org/openqa/selenium/ie/package-info.java +++ b/java/src/org/openqa/selenium/ie/package-info.java @@ -15,35 +15,6 @@ // specific language governing permissions and limitations // under the License. -/** - * Mechanisms to configure and run selenium via the command line. There are two key classes {@link - * org.openqa.selenium.cli.CliCommand} and {@link org.openqa.selenium.grid.config.HasRoles}. - * Ultimately, these are used to build a {@link org.openqa.selenium.grid.config.Config} instance, - * for which there are strongly-typed role-specific classes that use a {@code Config}, such as - * {@link org.openqa.selenium.grid.node.docker.DockerOptions}. - * - *

Assuming your {@code CliCommand} extends {@link org.openqa.selenium.grid.TemplateGridCommand}, - * the process for building the set of flags to use is: - * - *

    - *
  1. The default flags are added (these are {@link org.openqa.selenium.grid.server.HelpFlags} - * and {@link org.openqa.selenium.grid.config.ConfigFlags} - *
  2. {@link java.util.ServiceLoader} is used to find all implementations of {@link - * org.openqa.selenium.grid.config.HasRoles} where {@link - * org.openqa.selenium.grid.config.HasRoles#getRoles()} is contained within {@link - * org.openqa.selenium.cli.CliCommand#getConfigurableRoles()}. - *
  3. Finally all flags returned by {@link - * org.openqa.selenium.grid.TemplateGridCommand#getFlagObjects()} are added. - *
- * - *

The flags are then used by JCommander to parse the command arguments. Once that's done, the - * raw flags are converted to a {@link org.openqa.selenium.grid.config.Config} by combining all of - * the flag objects with system properties and environment variables. This implies that each flag - * object has annotated each field with {@link org.openqa.selenium.grid.config.ConfigValue}. - * - *

Ultimately, this means that flag objects have all (most?) fields annotated with JCommander's - * {@link com.beust.jcommander.Parameter} annotation as well as {@code ConfigValue}. - */ @NullMarked package org.openqa.selenium.ie; diff --git a/java/src/org/openqa/selenium/print/package-info.java b/java/src/org/openqa/selenium/print/package-info.java index 48ef4b6fe9f52..a1b118b15459b 100644 --- a/java/src/org/openqa/selenium/print/package-info.java +++ b/java/src/org/openqa/selenium/print/package-info.java @@ -15,35 +15,6 @@ // specific language governing permissions and limitations // under the License. -/** - * Mechanisms to configure and run selenium via the command line. There are two key classes {@link - * org.openqa.selenium.cli.CliCommand} and {@link org.openqa.selenium.grid.config.HasRoles}. - * Ultimately, these are used to build a {@link org.openqa.selenium.grid.config.Config} instance, - * for which there are strongly-typed role-specific classes that use a {@code Config}, such as - * {@link org.openqa.selenium.grid.node.docker.DockerOptions}. - * - *

Assuming your {@code CliCommand} extends {@link org.openqa.selenium.grid.TemplateGridCommand}, - * the process for building the set of flags to use is: - * - *

    - *
  1. The default flags are added (these are {@link org.openqa.selenium.grid.server.HelpFlags} - * and {@link org.openqa.selenium.grid.config.ConfigFlags} - *
  2. {@link java.util.ServiceLoader} is used to find all implementations of {@link - * org.openqa.selenium.grid.config.HasRoles} where {@link - * org.openqa.selenium.grid.config.HasRoles#getRoles()} is contained within {@link - * org.openqa.selenium.cli.CliCommand#getConfigurableRoles()}. - *
  3. Finally all flags returned by {@link - * org.openqa.selenium.grid.TemplateGridCommand#getFlagObjects()} are added. - *
- * - *

The flags are then used by JCommander to parse the command arguments. Once that's done, the - * raw flags are converted to a {@link org.openqa.selenium.grid.config.Config} by combining all of - * the flag objects with system properties and environment variables. This implies that each flag - * object has annotated each field with {@link org.openqa.selenium.grid.config.ConfigValue}. - * - *

Ultimately, this means that flag objects have all (most?) fields annotated with JCommander's - * {@link com.beust.jcommander.Parameter} annotation as well as {@code ConfigValue}. - */ @NullMarked package org.openqa.selenium.print; diff --git a/java/src/org/openqa/selenium/safari/package-info.java b/java/src/org/openqa/selenium/safari/package-info.java index 6684283ee6752..f679c88a7dc10 100644 --- a/java/src/org/openqa/selenium/safari/package-info.java +++ b/java/src/org/openqa/selenium/safari/package-info.java @@ -15,35 +15,6 @@ // specific language governing permissions and limitations // under the License. -/** - * Mechanisms to configure and run selenium via the command line. There are two key classes {@link - * org.openqa.selenium.cli.CliCommand} and {@link org.openqa.selenium.grid.config.HasRoles}. - * Ultimately, these are used to build a {@link org.openqa.selenium.grid.config.Config} instance, - * for which there are strongly-typed role-specific classes that use a {@code Config}, such as - * {@link org.openqa.selenium.grid.node.docker.DockerOptions}. - * - *

Assuming your {@code CliCommand} extends {@link org.openqa.selenium.grid.TemplateGridCommand}, - * the process for building the set of flags to use is: - * - *

    - *
  1. The default flags are added (these are {@link org.openqa.selenium.grid.server.HelpFlags} - * and {@link org.openqa.selenium.grid.config.ConfigFlags} - *
  2. {@link java.util.ServiceLoader} is used to find all implementations of {@link - * org.openqa.selenium.grid.config.HasRoles} where {@link - * org.openqa.selenium.grid.config.HasRoles#getRoles()} is contained within {@link - * org.openqa.selenium.cli.CliCommand#getConfigurableRoles()}. - *
  3. Finally all flags returned by {@link - * org.openqa.selenium.grid.TemplateGridCommand#getFlagObjects()} are added. - *
- * - *

The flags are then used by JCommander to parse the command arguments. Once that's done, the - * raw flags are converted to a {@link org.openqa.selenium.grid.config.Config} by combining all of - * the flag objects with system properties and environment variables. This implies that each flag - * object has annotated each field with {@link org.openqa.selenium.grid.config.ConfigValue}. - * - *

Ultimately, this means that flag objects have all (most?) fields annotated with JCommander's - * {@link com.beust.jcommander.Parameter} annotation as well as {@code ConfigValue}. - */ @NullMarked package org.openqa.selenium.safari; From 8ba5f195262b23492cccea69ebb658b5fd721620 Mon Sep 17 00:00:00 2001 From: Andrei Solntsev Date: Wed, 4 Mar 2026 11:56:22 +0200 Subject: [PATCH 2/2] specify nullability in package `org.openqa.selenium.grid` --- .../openqa/selenium/MutableCapabilities.java | 2 +- .../selenium/SessionNotCreatedException.java | 6 +- java/src/org/openqa/selenium/cli/BUILD.bazel | 1 + .../org/openqa/selenium/cli/package-info.java | 3 + java/src/org/openqa/selenium/grid/BUILD.bazel | 2 + .../grid/TemplateGridServerCommand.java | 17 ++-- .../selenium/grid/commands/InfoCommand.java | 2 - .../selenium/grid/commands/package-info.java | 21 ++++ .../selenium/grid/component/BUILD.bazel | 2 + .../selenium/grid/component/package-info.java | 21 ++++ .../selenium/grid/config/AnnotatedConfig.java | 4 +- .../openqa/selenium/grid/config/BUILD.bazel | 1 + .../grid/config/ConcatenatingConfig.java | 3 +- .../openqa/selenium/grid/config/Config.java | 3 +- .../selenium/grid/config/ConfigException.java | 4 +- .../selenium/grid/config/MemoizedConfig.java | 5 +- .../selenium/grid/config/package-info.java | 21 ++++ .../org/openqa/selenium/grid/data/BUILD.bazel | 2 + .../selenium/grid/data/CapabilityCount.java | 1 + .../grid/data/CreateSessionRequest.java | 1 + .../grid/data/CreateSessionResponse.java | 1 + .../selenium/grid/data/DistributorStatus.java | 1 + .../grid/data/NewSessionErrorResponse.java | 1 + .../grid/data/NewSessionResponse.java | 1 + .../org/openqa/selenium/grid/data/NodeId.java | 1 + .../openqa/selenium/grid/data/NodeStatus.java | 3 +- .../openqa/selenium/grid/data/RequestId.java | 1 + .../openqa/selenium/grid/data/Session.java | 3 +- .../selenium/grid/data/SessionClosedData.java | 25 +++-- .../grid/data/SessionCreatedData.java | 1 + .../selenium/grid/data/SessionEventData.java | 16 ++-- .../grid/data/SessionRemovalInfo.java | 5 +- .../selenium/grid/data/SessionRequest.java | 1 + .../grid/data/SessionRequestCapability.java | 8 +- .../org/openqa/selenium/grid/data/Slot.java | 11 ++- .../org/openqa/selenium/grid/data/SlotId.java | 1 + .../selenium/grid/data/package-info.java | 21 ++++ .../selenium/grid/distributor/AddNode.java | 4 +- .../selenium/grid/distributor/BUILD.bazel | 1 + .../selenium/grid/distributor/GridModel.java | 3 +- .../grid/distributor/NodeRegistry.java | 5 +- .../grid/distributor/config/BUILD.bazel | 1 + .../grid/distributor/config/package-info.java | 21 ++++ .../grid/distributor/httpd/BUILD.bazel | 1 + .../grid/distributor/httpd/package-info.java | 21 ++++ .../grid/distributor/local/BUILD.bazel | 1 + .../distributor/local/LocalDistributor.java | 3 + .../distributor/local/LocalGridModel.java | 8 +- .../distributor/local/LocalNodeRegistry.java | 4 +- .../grid/distributor/local/package-info.java | 21 ++++ .../grid/distributor/package-info.java | 3 + .../grid/distributor/remote/BUILD.bazel | 2 + .../grid/distributor/remote/package-info.java | 21 ++++ .../grid/distributor/selector/BUILD.bazel | 1 + .../distributor/selector/package-info.java | 21 ++++ .../openqa/selenium/grid/graphql/BUILD.bazel | 1 + .../selenium/grid/graphql/SessionData.java | 2 + .../openqa/selenium/grid/graphql/Types.java | 8 +- .../selenium/grid/graphql/package-info.java | 21 ++++ .../openqa/selenium/grid/jmx/JMXHelper.java | 4 +- .../org/openqa/selenium/grid/jmx/MBean.java | 4 +- .../selenium/grid/jmx/package-info.java | 21 ++++ .../org/openqa/selenium/grid/log/BUILD.bazel | 1 + .../selenium/grid/log/FlushingHandler.java | 3 +- .../selenium/grid/log/LoggingOptions.java | 4 +- .../selenium/grid/log/package-info.java | 21 ++++ .../org/openqa/selenium/grid/node/Node.java | 3 + .../selenium/grid/node/config/BUILD.bazel | 1 + .../config/DriverServiceSessionFactory.java | 2 + .../grid/node/config/NodeOptions.java | 2 +- .../config/SessionCapabilitiesMutator.java | 9 +- .../grid/node/config/package-info.java | 21 ++++ .../selenium/grid/node/docker/BUILD.bazel | 1 + .../grid/node/docker/DockerOptions.java | 4 + .../grid/node/docker/DockerSession.java | 5 +- .../node/docker/DockerSessionFactory.java | 18 ++-- .../grid/node/docker/package-info.java | 21 ++++ .../selenium/grid/node/httpd/BUILD.bazel | 1 + .../selenium/grid/node/httpd/NodeServer.java | 5 +- .../grid/node/httpd/package-info.java | 21 ++++ .../openqa/selenium/grid/node/k8s/BUILD.bazel | 1 + .../selenium/grid/node/k8s/OneShotNode.java | 12 ++- .../selenium/grid/node/k8s/package-info.java | 21 ++++ .../selenium/grid/node/kubernetes/BUILD.bazel | 1 + .../node/kubernetes/InheritedPodSpec.java | 95 +++++++++++-------- .../node/kubernetes/KubernetesOptions.java | 17 +++- .../node/kubernetes/KubernetesSession.java | 13 +-- .../kubernetes/KubernetesSessionFactory.java | 58 ++++++----- .../grid/node/kubernetes/package-info.java | 21 ++++ .../selenium/grid/node/local/BUILD.bazel | 1 + .../selenium/grid/node/local/LocalNode.java | 8 +- .../selenium/grid/node/local/SessionSlot.java | 6 +- .../grid/node/local/package-info.java | 21 ++++ .../selenium/grid/node/package-info.java | 21 ++++ .../selenium/grid/node/relay/BUILD.bazel | 1 + .../grid/node/relay/RelayOptions.java | 5 +- .../grid/node/relay/RelaySessionFactory.java | 13 +-- .../grid/node/relay/package-info.java | 21 ++++ .../selenium/grid/node/remote/BUILD.bazel | 1 + .../selenium/grid/node/remote/RemoteNode.java | 4 +- .../grid/node/remote/package-info.java | 21 ++++ .../openqa/selenium/grid/package-info.java | 6 +- .../openqa/selenium/grid/router/BUILD.bazel | 1 + .../selenium/grid/router/httpd/BUILD.bazel | 1 + .../grid/router/httpd/package-info.java | 21 ++++ .../selenium/grid/router/package-info.java | 21 ++++ .../openqa/selenium/grid/security/BUILD.bazel | 1 + .../security/BasicAuthenticationFilter.java | 3 +- .../selenium/grid/security/SecretOptions.java | 2 + .../selenium/grid/security/package-info.java | 21 ++++ .../openqa/selenium/grid/server/BUILD.bazel | 1 + .../grid/server/BaseServerOptions.java | 3 +- .../selenium/grid/server/EventBusOptions.java | 3 +- .../selenium/grid/server/package-info.java | 21 ++++ .../openqa/selenium/grid/session/BUILD.bazel | 1 + .../selenium/grid/session/package-info.java | 21 ++++ .../selenium/grid/sessionmap/BUILD.bazel | 1 + .../grid/sessionmap/config/BUILD.bazel | 1 + .../grid/sessionmap/config/package-info.java | 21 ++++ .../grid/sessionmap/httpd/BUILD.bazel | 1 + .../grid/sessionmap/httpd/package-info.java | 21 ++++ .../sessionmap/jdbc/JdbcBackedSessionMap.java | 13 +-- .../grid/sessionmap/jdbc/package-info.java | 21 ++++ .../grid/sessionmap/local/BUILD.bazel | 1 + .../sessionmap/local/LocalSessionMap.java | 3 + .../grid/sessionmap/local/package-info.java | 21 ++++ .../grid/sessionmap/package-info.java | 21 ++++ .../grid/sessionmap/redis/BUILD.bazel | 1 + .../redis/RedisBackedSessionMap.java | 8 +- .../grid/sessionmap/redis/package-info.java | 21 ++++ .../grid/sessionmap/remote/BUILD.bazel | 2 + .../sessionmap/remote/RemoteSessionMap.java | 5 +- .../grid/sessionmap/remote/package-info.java | 21 ++++ .../selenium/grid/sessionqueue/BUILD.bazel | 1 + .../grid/sessionqueue/config/BUILD.bazel | 1 + .../sessionqueue/config/package-info.java | 21 ++++ .../grid/sessionqueue/httpd/BUILD.bazel | 1 + .../grid/sessionqueue/httpd/package-info.java | 21 ++++ .../grid/sessionqueue/local/BUILD.bazel | 1 + .../local/LocalNewSessionQueue.java | 4 +- .../grid/sessionqueue/local/package-info.java | 21 ++++ .../grid/sessionqueue/package-info.java | 21 ++++ .../grid/sessionqueue/remote/BUILD.bazel | 1 + .../sessionqueue/remote/package-info.java | 21 ++++ .../org/openqa/selenium/grid/web/BUILD.bazel | 1 + .../selenium/grid/web/MergedResource.java | 3 +- .../openqa/selenium/grid/web/NoHandler.java | 3 +- .../org/openqa/selenium/grid/web/Values.java | 2 +- .../selenium/grid/web/package-info.java | 21 ++++ .../selenium/ie/InternetExplorerOptions.java | 8 +- .../org/openqa/selenium/internal/Debug.java | 3 +- .../org/openqa/selenium/manager/BUILD.bazel | 1 + .../selenium/manager/SeleniumManager.java | 9 +- .../manager/SeleniumManagerOutput.java | 22 +++-- .../openqa/selenium/manager/package-info.java | 21 ++++ .../org/openqa/selenium/net/UrlChecker.java | 5 +- .../remote/AbstractDriverOptions.java | 29 ++++-- .../openqa/selenium/remote/RemoteLogs.java | 24 ++--- .../openqa/selenium/grid/config/BUILD.bazel | 1 + .../selenium/grid/config/package-info.java | 21 ++++ .../org/openqa/selenium/grid/data/BUILD.bazel | 1 + .../grid/data/DefaultSlotMatcherTest.java | 1 + .../selenium/grid/data/package-info.java | 21 ++++ .../grid/distributor/AddingNodesTest.java | 5 +- .../selenium/grid/distributor/BUILD.bazel | 1 + .../grid/distributor/local/BUILD.bazel | 1 + .../local/LocalNodeRegistryTest.java | 1 + .../grid/distributor/local/package-info.java | 21 ++++ .../grid/distributor/package-info.java | 21 ++++ .../grid/distributor/selector/BUILD.bazel | 1 + .../distributor/selector/package-info.java | 21 ++++ .../openqa/selenium/grid/graphql/BUILD.bazel | 1 + .../selenium/grid/graphql/package-info.java | 21 ++++ .../openqa/selenium/grid/gridui/BUILD.bazel | 1 + .../selenium/grid/gridui/package-info.java | 21 ++++ .../org/openqa/selenium/grid/node/BUILD.bazel | 1 + .../grid/node/ProxyNodeWebsocketsTest.java | 8 +- .../selenium/grid/node/config/BUILD.bazel | 2 + .../SessionCapabilitiesMutatorTest.java | 54 ++++++----- .../grid/node/config/package-info.java | 21 ++++ .../selenium/grid/node/data/BUILD.bazel | 2 + .../selenium/grid/node/data/package-info.java | 21 ++++ .../selenium/grid/node/docker/BUILD.bazel | 1 + .../grid/node/docker/package-info.java | 21 ++++ .../selenium/grid/node/kubernetes/BUILD.bazel | 1 + .../grid/node/kubernetes/package-info.java | 21 ++++ .../selenium/grid/node/local/BUILD.bazel | 1 + .../grid/node/local/package-info.java | 21 ++++ .../selenium/grid/node/package-info.java | 21 ++++ .../selenium/grid/node/relay/BUILD.bazel | 1 + .../grid/node/relay/package-info.java | 21 ++++ .../openqa/selenium/grid/router/BUILD.bazel | 5 + .../grid/router/RemoteWebDriverBiDiTest.java | 1 + .../grid/router/SessionCleanUpTest.java | 1 + .../selenium/grid/router/package-info.java | 21 ++++ .../openqa/selenium/grid/security/BUILD.bazel | 1 + .../selenium/grid/security/package-info.java | 21 ++++ .../openqa/selenium/grid/server/BUILD.bazel | 1 + .../selenium/grid/server/package-info.java | 21 ++++ .../selenium/remote/RemoteLogsTest.java | 2 +- 200 files changed, 1689 insertions(+), 271 deletions(-) create mode 100644 java/src/org/openqa/selenium/grid/commands/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/component/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/config/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/data/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/distributor/config/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/distributor/httpd/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/distributor/local/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/distributor/remote/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/distributor/selector/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/graphql/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/jmx/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/log/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/node/config/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/node/docker/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/node/httpd/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/node/k8s/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/node/kubernetes/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/node/local/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/node/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/node/relay/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/node/remote/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/router/httpd/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/router/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/security/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/server/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/session/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/sessionmap/config/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/sessionmap/httpd/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/sessionmap/jdbc/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/sessionmap/local/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/sessionmap/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/sessionmap/redis/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/sessionmap/remote/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/sessionqueue/config/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/sessionqueue/httpd/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/sessionqueue/local/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/sessionqueue/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/sessionqueue/remote/package-info.java create mode 100644 java/src/org/openqa/selenium/grid/web/package-info.java create mode 100644 java/src/org/openqa/selenium/manager/package-info.java create mode 100644 java/test/org/openqa/selenium/grid/config/package-info.java create mode 100644 java/test/org/openqa/selenium/grid/data/package-info.java create mode 100644 java/test/org/openqa/selenium/grid/distributor/local/package-info.java create mode 100644 java/test/org/openqa/selenium/grid/distributor/package-info.java create mode 100644 java/test/org/openqa/selenium/grid/distributor/selector/package-info.java create mode 100644 java/test/org/openqa/selenium/grid/graphql/package-info.java create mode 100644 java/test/org/openqa/selenium/grid/gridui/package-info.java create mode 100644 java/test/org/openqa/selenium/grid/node/config/package-info.java create mode 100644 java/test/org/openqa/selenium/grid/node/data/package-info.java create mode 100644 java/test/org/openqa/selenium/grid/node/docker/package-info.java create mode 100644 java/test/org/openqa/selenium/grid/node/kubernetes/package-info.java create mode 100644 java/test/org/openqa/selenium/grid/node/local/package-info.java create mode 100644 java/test/org/openqa/selenium/grid/node/package-info.java create mode 100644 java/test/org/openqa/selenium/grid/node/relay/package-info.java create mode 100644 java/test/org/openqa/selenium/grid/router/package-info.java create mode 100644 java/test/org/openqa/selenium/grid/security/package-info.java create mode 100644 java/test/org/openqa/selenium/grid/server/package-info.java diff --git a/java/src/org/openqa/selenium/MutableCapabilities.java b/java/src/org/openqa/selenium/MutableCapabilities.java index 5d9081eeb66d7..37d68ffceb868 100644 --- a/java/src/org/openqa/selenium/MutableCapabilities.java +++ b/java/src/org/openqa/selenium/MutableCapabilities.java @@ -74,7 +74,7 @@ public void setCapability(String capabilityName, boolean value) { setCapability(capabilityName, (Object) value); } - public void setCapability(String capabilityName, String value) { + public void setCapability(String capabilityName, @Nullable String value) { setCapability(capabilityName, (Object) value); } diff --git a/java/src/org/openqa/selenium/SessionNotCreatedException.java b/java/src/org/openqa/selenium/SessionNotCreatedException.java index 30bb9d6c2ab21..47e397dab835f 100644 --- a/java/src/org/openqa/selenium/SessionNotCreatedException.java +++ b/java/src/org/openqa/selenium/SessionNotCreatedException.java @@ -17,16 +17,18 @@ package org.openqa.selenium; +import org.jspecify.annotations.Nullable; + /** Indicates that a session could not be created. */ public class SessionNotCreatedException extends WebDriverException { - public SessionNotCreatedException(String msg) { + public SessionNotCreatedException(@Nullable String msg) { super( "Could not start a new session. " + msg + (msg != null && msg.contains("Host info") ? "" : " \n" + getHostInformation())); } - public SessionNotCreatedException(String msg, Throwable cause) { + public SessionNotCreatedException(@Nullable String msg, @Nullable Throwable cause) { super( "Could not start a new session. " + msg diff --git a/java/src/org/openqa/selenium/cli/BUILD.bazel b/java/src/org/openqa/selenium/cli/BUILD.bazel index 663b7e81ac101..1a621c3b5000e 100644 --- a/java/src/org/openqa/selenium/cli/BUILD.bazel +++ b/java/src/org/openqa/selenium/cli/BUILD.bazel @@ -9,5 +9,6 @@ java_library( deps = [ "//java/src/org/openqa/selenium:core", "//java/src/org/openqa/selenium/grid/config", + "@maven//:org_jspecify_jspecify", ], ) diff --git a/java/src/org/openqa/selenium/cli/package-info.java b/java/src/org/openqa/selenium/cli/package-info.java index 2e3f8d91a4c4a..68be944df3d78 100644 --- a/java/src/org/openqa/selenium/cli/package-info.java +++ b/java/src/org/openqa/selenium/cli/package-info.java @@ -44,4 +44,7 @@ *

Ultimately, this means that flag objects have all (most?) fields annotated with JCommander's * {@link com.beust.jcommander.Parameter} annotation as well as {@code ConfigValue}. */ +@NullMarked package org.openqa.selenium.cli; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/BUILD.bazel b/java/src/org/openqa/selenium/grid/BUILD.bazel index 2b4e66a98c449..dcc5b7f0e2c82 100644 --- a/java/src/org/openqa/selenium/grid/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/BUILD.bazel @@ -89,6 +89,7 @@ java_library( "//java/src/org/openqa/selenium/remote/http", artifact("com.beust:jcommander"), artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) @@ -171,6 +172,7 @@ java_export( ":base-command", "//java/src/org/openqa/selenium/cli", "//java/src/org/openqa/selenium/grid/config", + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/TemplateGridServerCommand.java b/java/src/org/openqa/selenium/grid/TemplateGridServerCommand.java index 0c8e82b4b692a..963b445d6435b 100644 --- a/java/src/org/openqa/selenium/grid/TemplateGridServerCommand.java +++ b/java/src/org/openqa/selenium/grid/TemplateGridServerCommand.java @@ -26,6 +26,7 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.grid.config.CompoundConfig; import org.openqa.selenium.grid.config.Config; import org.openqa.selenium.grid.config.MemoizedConfig; @@ -91,24 +92,26 @@ protected static Routable baseRoute(String prefix, Route route) { protected abstract Handlers createHandlers(Config config); - public abstract static class Handlers implements Closeable { + protected abstract static class Handlers implements Closeable { public final HttpHandler httpHandler; public final BiFunction, Optional>> websocketHandler; /** Optional resolver for direct TCP tunnel of WebSocket connections. May be null. */ - public final Function> tcpTunnelResolver; + public final @Nullable Function> tcpTunnelResolver; - public Handlers( + protected Handlers( HttpHandler http, - BiFunction, Optional>> websocketHandler) { + @Nullable BiFunction, Optional>> + websocketHandler) { this(http, websocketHandler, null); } - public Handlers( + protected Handlers( HttpHandler http, - BiFunction, Optional>> websocketHandler, - Function> tcpTunnelResolver) { + @Nullable BiFunction, Optional>> + websocketHandler, + @Nullable Function> tcpTunnelResolver) { this.httpHandler = Require.nonNull("HTTP handler", http); this.websocketHandler = websocketHandler == null ? (str, sink) -> Optional.empty() : websocketHandler; diff --git a/java/src/org/openqa/selenium/grid/commands/InfoCommand.java b/java/src/org/openqa/selenium/grid/commands/InfoCommand.java index 41db14a988552..3fcbf02e2df51 100644 --- a/java/src/org/openqa/selenium/grid/commands/InfoCommand.java +++ b/java/src/org/openqa/selenium/grid/commands/InfoCommand.java @@ -34,7 +34,6 @@ import java.util.Collections; import java.util.Set; import java.util.regex.Pattern; -import org.jspecify.annotations.NonNull; import org.openqa.selenium.cli.CliCommand; import org.openqa.selenium.cli.WrappedPrintWriter; import org.openqa.selenium.grid.config.Role; @@ -169,7 +168,6 @@ private String readContent(String path) throws IOException { return formattedText.toString(); } - @NonNull private String unformattedText(String path) throws IOException { try (InputStream in = getClass().getClassLoader().getResourceAsStream(path)) { requireNonNull(in, () -> "Resource is not found in classpath: " + path); diff --git a/java/src/org/openqa/selenium/grid/commands/package-info.java b/java/src/org/openqa/selenium/grid/commands/package-info.java new file mode 100644 index 0000000000000..d57f8ca1ce6b9 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/commands/package-info.java @@ -0,0 +1,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.grid.commands; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/component/BUILD.bazel b/java/src/org/openqa/selenium/grid/component/BUILD.bazel index e4692451e6921..8160be880f20f 100644 --- a/java/src/org/openqa/selenium/grid/component/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/component/BUILD.bazel @@ -1,3 +1,4 @@ +load("@rules_jvm_external//:defs.bzl", "artifact") load("//java:defs.bzl", "java_library") java_library( @@ -10,5 +11,6 @@ java_library( ], deps = [ "//java/src/org/openqa/selenium:core", + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/component/package-info.java b/java/src/org/openqa/selenium/grid/component/package-info.java new file mode 100644 index 0000000000000..eaa2be1630be9 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/component/package-info.java @@ -0,0 +1,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.grid.component; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/config/AnnotatedConfig.java b/java/src/org/openqa/selenium/grid/config/AnnotatedConfig.java index f963f87436b7f..7476063aeab3d 100644 --- a/java/src/org/openqa/selenium/grid/config/AnnotatedConfig.java +++ b/java/src/org/openqa/selenium/grid/config/AnnotatedConfig.java @@ -35,6 +35,7 @@ import java.util.Map; import java.util.Optional; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.internal.Require; /** @@ -108,7 +109,8 @@ public AnnotatedConfig(Object obj, Set cliArgs, boolean includeCliArgs) this.config = values; } - private String getSingleValue(Object value) { + @Nullable + private String getSingleValue(@Nullable Object value) { if (value == null) { return null; } diff --git a/java/src/org/openqa/selenium/grid/config/BUILD.bazel b/java/src/org/openqa/selenium/grid/config/BUILD.bazel index e2be2a4b14de7..92344f484eb73 100644 --- a/java/src/org/openqa/selenium/grid/config/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/config/BUILD.bazel @@ -22,5 +22,6 @@ java_library( artifact("com.beust:jcommander"), artifact("com.google.guava:guava"), artifact("org.tomlj:tomlj"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/config/ConcatenatingConfig.java b/java/src/org/openqa/selenium/grid/config/ConcatenatingConfig.java index 56e7b6e72bbd2..6f9aa1691624f 100644 --- a/java/src/org/openqa/selenium/grid/config/ConcatenatingConfig.java +++ b/java/src/org/openqa/selenium/grid/config/ConcatenatingConfig.java @@ -26,6 +26,7 @@ import java.util.Map; import java.util.Optional; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.internal.Require; public class ConcatenatingConfig implements Config { @@ -34,7 +35,7 @@ public class ConcatenatingConfig implements Config { private final char separator; private final Map values; - public ConcatenatingConfig(String prefix, char separator, Map values) { + public ConcatenatingConfig(@Nullable String prefix, char separator, Map values) { this.prefix = prefix == null || prefix.isEmpty() ? "" : (prefix + separator); this.separator = separator; diff --git a/java/src/org/openqa/selenium/grid/config/Config.java b/java/src/org/openqa/selenium/grid/config/Config.java index c4eb7e2263519..16424bd5a7aa1 100644 --- a/java/src/org/openqa/selenium/grid/config/Config.java +++ b/java/src/org/openqa/selenium/grid/config/Config.java @@ -24,6 +24,7 @@ import java.util.Set; import java.util.logging.Logger; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.json.Json; public interface Config { @@ -34,7 +35,7 @@ public interface Config { Optional> getAll(String section, String option); - default Optional get(String section, String option) { + default Optional<@Nullable String> get(String section, String option) { return getAll(section, option).map(items -> items.isEmpty() ? null : items.get(0)); } diff --git a/java/src/org/openqa/selenium/grid/config/ConfigException.java b/java/src/org/openqa/selenium/grid/config/ConfigException.java index cf4a0bcd818a7..e396ca26ae671 100644 --- a/java/src/org/openqa/selenium/grid/config/ConfigException.java +++ b/java/src/org/openqa/selenium/grid/config/ConfigException.java @@ -17,13 +17,15 @@ package org.openqa.selenium.grid.config; +import org.jspecify.annotations.Nullable; + public class ConfigException extends RuntimeException { public ConfigException(String message, Object... args) { super(String.format(message, args)); } - public ConfigException(Throwable cause) { + public ConfigException(@Nullable Throwable cause) { super(cause); } } diff --git a/java/src/org/openqa/selenium/grid/config/MemoizedConfig.java b/java/src/org/openqa/selenium/grid/config/MemoizedConfig.java index a111b5af68759..34c8a34826c3a 100644 --- a/java/src/org/openqa/selenium/grid/config/MemoizedConfig.java +++ b/java/src/org/openqa/selenium/grid/config/MemoizedConfig.java @@ -24,6 +24,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicReference; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.internal.Require; public class MemoizedConfig implements Config { @@ -61,7 +62,7 @@ public Optional> getAll(String section, String option) { } @Override - public Optional get(String section, String option) { + public Optional<@Nullable String> get(String section, String option) { Require.nonNull("Section name", section); Require.nonNull("Option", option); @@ -94,7 +95,7 @@ public X getClass(String section, String option, Class typeOfX, String de Require.nonNull("Type to load", typeOfX); Require.nonNull("Default class name", defaultClassName); - AtomicReference thrown = new AtomicReference<>(); + AtomicReference<@Nullable Exception> thrown = new AtomicReference<>(); Object value = seenClasses.computeIfAbsent( new Key(section, option, typeOfX.toGenericString(), defaultClassName), diff --git a/java/src/org/openqa/selenium/grid/config/package-info.java b/java/src/org/openqa/selenium/grid/config/package-info.java new file mode 100644 index 0000000000000..f1393763f3149 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/config/package-info.java @@ -0,0 +1,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.grid.config; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/data/BUILD.bazel b/java/src/org/openqa/selenium/grid/data/BUILD.bazel index 761bf51d92992..175cf061f84eb 100644 --- a/java/src/org/openqa/selenium/grid/data/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/data/BUILD.bazel @@ -1,3 +1,4 @@ +load("@rules_jvm_external//:defs.bzl", "artifact") load("//java:defs.bzl", "java_library") java_library( @@ -15,5 +16,6 @@ java_library( "//java/src/org/openqa/selenium/grid/security", "//java/src/org/openqa/selenium/json", "//java/src/org/openqa/selenium/remote", + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/data/CapabilityCount.java b/java/src/org/openqa/selenium/grid/data/CapabilityCount.java index f04af7680fc2c..4e2e877b8831a 100644 --- a/java/src/org/openqa/selenium/grid/data/CapabilityCount.java +++ b/java/src/org/openqa/selenium/grid/data/CapabilityCount.java @@ -60,6 +60,7 @@ private Object toJson() { UNORDERED)); } + @SuppressWarnings({"unused", "DataFlowIssue"}) private static CapabilityCount fromJson(JsonInput input) { Map toReturn = new HashMap<>(); diff --git a/java/src/org/openqa/selenium/grid/data/CreateSessionRequest.java b/java/src/org/openqa/selenium/grid/data/CreateSessionRequest.java index e89ba10f81886..3c811f91af481 100644 --- a/java/src/org/openqa/selenium/grid/data/CreateSessionRequest.java +++ b/java/src/org/openqa/selenium/grid/data/CreateSessionRequest.java @@ -56,6 +56,7 @@ public Map getMetadata() { return metadata; } + @SuppressWarnings({"unused", "DataFlowIssue"}) private static CreateSessionRequest fromJson(JsonInput input) { Set downstreamDialects = null; Capabilities capabilities = null; diff --git a/java/src/org/openqa/selenium/grid/data/CreateSessionResponse.java b/java/src/org/openqa/selenium/grid/data/CreateSessionResponse.java index 10a0e24c9f585..0cf73a231d77a 100644 --- a/java/src/org/openqa/selenium/grid/data/CreateSessionResponse.java +++ b/java/src/org/openqa/selenium/grid/data/CreateSessionResponse.java @@ -52,6 +52,7 @@ private Map toJson() { return unmodifiableMap(toReturn); } + @SuppressWarnings({"unused", "DataFlowIssue"}) private static CreateSessionResponse fromJson(JsonInput input) { Session session = null; byte[] downstreamResponse = null; diff --git a/java/src/org/openqa/selenium/grid/data/DistributorStatus.java b/java/src/org/openqa/selenium/grid/data/DistributorStatus.java index d989ac3c842d5..208d5d6bceba2 100644 --- a/java/src/org/openqa/selenium/grid/data/DistributorStatus.java +++ b/java/src/org/openqa/selenium/grid/data/DistributorStatus.java @@ -52,6 +52,7 @@ private Map toJson() { return Collections.singletonMap("nodes", getNodes()); } + @SuppressWarnings({"unused", "DataFlowIssue"}) private static DistributorStatus fromJson(JsonInput input) { Set nodes = null; diff --git a/java/src/org/openqa/selenium/grid/data/NewSessionErrorResponse.java b/java/src/org/openqa/selenium/grid/data/NewSessionErrorResponse.java index 1cfba61c8e111..a7e9dc363c750 100644 --- a/java/src/org/openqa/selenium/grid/data/NewSessionErrorResponse.java +++ b/java/src/org/openqa/selenium/grid/data/NewSessionErrorResponse.java @@ -49,6 +49,7 @@ private Map toJson() { return unmodifiableMap(toReturn); } + @SuppressWarnings({"unused", "DataFlowIssue"}) private static NewSessionErrorResponse fromJson(JsonInput input) { String message = null; RequestId requestId = null; diff --git a/java/src/org/openqa/selenium/grid/data/NewSessionResponse.java b/java/src/org/openqa/selenium/grid/data/NewSessionResponse.java index c0a20a443f97a..5e7d7599909c1 100644 --- a/java/src/org/openqa/selenium/grid/data/NewSessionResponse.java +++ b/java/src/org/openqa/selenium/grid/data/NewSessionResponse.java @@ -60,6 +60,7 @@ private Map toJson() { return unmodifiableMap(toReturn); } + @SuppressWarnings({"unused", "DataFlowIssue"}) private static NewSessionResponse fromJson(JsonInput input) { RequestId requestId = null; Session session = null; diff --git a/java/src/org/openqa/selenium/grid/data/NodeId.java b/java/src/org/openqa/selenium/grid/data/NodeId.java index cae18693b8fa8..f5393d356a86a 100644 --- a/java/src/org/openqa/selenium/grid/data/NodeId.java +++ b/java/src/org/openqa/selenium/grid/data/NodeId.java @@ -64,6 +64,7 @@ private Object toJson() { return uuid; } + @SuppressWarnings({"unused"}) private static NodeId fromJson(UUID id) { return new NodeId(id); } diff --git a/java/src/org/openqa/selenium/grid/data/NodeStatus.java b/java/src/org/openqa/selenium/grid/data/NodeStatus.java index 010ed40b81281..aabf309d09a99 100644 --- a/java/src/org/openqa/selenium/grid/data/NodeStatus.java +++ b/java/src/org/openqa/selenium/grid/data/NodeStatus.java @@ -69,7 +69,8 @@ public NodeStatus( this.osInfo = Require.nonNull("Node host OS info", osInfo); } - public static NodeStatus fromJson(JsonInput input) { + @SuppressWarnings({"unused", "DataFlowIssue"}) + private static NodeStatus fromJson(JsonInput input) { NodeId nodeId = null; URI externalUri = null; int maxSessions = 0; diff --git a/java/src/org/openqa/selenium/grid/data/RequestId.java b/java/src/org/openqa/selenium/grid/data/RequestId.java index 1b7ddd3fb3af6..7bdae7ca2c7c5 100644 --- a/java/src/org/openqa/selenium/grid/data/RequestId.java +++ b/java/src/org/openqa/selenium/grid/data/RequestId.java @@ -57,6 +57,7 @@ private Object toJson() { return uuid; } + @SuppressWarnings({"unused"}) private static RequestId fromJson(UUID id) { return new RequestId(id); } diff --git a/java/src/org/openqa/selenium/grid/data/Session.java b/java/src/org/openqa/selenium/grid/data/Session.java index 061cbfb6b212e..7d51e6023f0a3 100644 --- a/java/src/org/openqa/selenium/grid/data/Session.java +++ b/java/src/org/openqa/selenium/grid/data/Session.java @@ -90,6 +90,7 @@ private Map toJson() { return unmodifiableMap(toReturn); } + @SuppressWarnings({"unused", "DataFlowIssue"}) private static Session fromJson(JsonInput input) { SessionId id = null; URI uri = null; @@ -101,7 +102,7 @@ private static Session fromJson(JsonInput input) { while (input.hasNext()) { switch (input.nextName()) { case "capabilities": - caps = ImmutableCapabilities.copyOf(input.read(Capabilities.class)); + caps = ImmutableCapabilities.copyOf(input.readNonNull(Capabilities.class)); break; case "sessionId": diff --git a/java/src/org/openqa/selenium/grid/data/SessionClosedData.java b/java/src/org/openqa/selenium/grid/data/SessionClosedData.java index 4fdfac5f10ebc..1dff56c87b150 100644 --- a/java/src/org/openqa/selenium/grid/data/SessionClosedData.java +++ b/java/src/org/openqa/selenium/grid/data/SessionClosedData.java @@ -22,6 +22,7 @@ import java.time.Instant; import java.util.Map; import java.util.TreeMap; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.Capabilities; import org.openqa.selenium.internal.Require; import org.openqa.selenium.json.JsonException; @@ -37,10 +38,10 @@ public class SessionClosedData { private final SessionId sessionId; private final SessionClosedReason reason; - private final NodeId nodeId; - private final URI nodeUri; - private final Capabilities capabilities; - private final Instant startTime; + private final @Nullable NodeId nodeId; + private final @Nullable URI nodeUri; + private final @Nullable Capabilities capabilities; + private final @Nullable Instant startTime; private final Instant endTime; /** Backward compatible constructor for existing code. */ @@ -52,10 +53,10 @@ public SessionClosedData(SessionId sessionId, SessionClosedReason reason) { public SessionClosedData( SessionId sessionId, SessionClosedReason reason, - NodeId nodeId, - URI nodeUri, - Capabilities capabilities, - Instant startTime, + @Nullable NodeId nodeId, + @Nullable URI nodeUri, + @Nullable Capabilities capabilities, + @Nullable Instant startTime, Instant endTime) { this.sessionId = Require.nonNull("Session ID", sessionId); this.reason = Require.nonNull("Reason", reason); @@ -74,18 +75,22 @@ public SessionClosedReason getReason() { return reason; } + @Nullable public NodeId getNodeId() { return nodeId; } + @Nullable public URI getNodeUri() { return nodeUri; } + @Nullable public Capabilities getCapabilities() { return capabilities; } + @Nullable public Instant getStartTime() { return startTime; } @@ -99,8 +104,9 @@ public Instant getEndTime() { * * @return the session duration, or null if start time was not recorded */ + @Nullable public Duration getSessionDuration() { - if (startTime == null || endTime == null) { + if (startTime == null) { return null; } return Duration.between(startTime, endTime); @@ -132,6 +138,7 @@ private Map toJson() { return result; } + @SuppressWarnings({"unused", "DataFlowIssue"}) private static SessionClosedData fromJson(JsonInput input) { SessionId sessionId = null; SessionClosedReason reason = null; diff --git a/java/src/org/openqa/selenium/grid/data/SessionCreatedData.java b/java/src/org/openqa/selenium/grid/data/SessionCreatedData.java index e3900efb8eea3..82b6d7630053d 100644 --- a/java/src/org/openqa/selenium/grid/data/SessionCreatedData.java +++ b/java/src/org/openqa/selenium/grid/data/SessionCreatedData.java @@ -104,6 +104,7 @@ private Map toJson() { return toReturn; } + @SuppressWarnings({"unused", "DataFlowIssue"}) private static SessionCreatedData fromJson(JsonInput input) { SessionId sessionId = null; NodeId nodeId = null; diff --git a/java/src/org/openqa/selenium/grid/data/SessionEventData.java b/java/src/org/openqa/selenium/grid/data/SessionEventData.java index a2a7977e19142..ad3d8cb9bc131 100644 --- a/java/src/org/openqa/selenium/grid/data/SessionEventData.java +++ b/java/src/org/openqa/selenium/grid/data/SessionEventData.java @@ -22,6 +22,7 @@ import java.util.Collections; import java.util.Map; import java.util.TreeMap; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.internal.Require; import org.openqa.selenium.json.JsonInput; import org.openqa.selenium.remote.SessionId; @@ -75,18 +76,18 @@ public class SessionEventData { private final SessionId sessionId; private final String eventType; - private final NodeId nodeId; - private final URI nodeUri; + private final @Nullable NodeId nodeId; + private final @Nullable URI nodeUri; private final Instant timestamp; private final Map payload; public SessionEventData( SessionId sessionId, String eventType, - NodeId nodeId, - URI nodeUri, + @Nullable NodeId nodeId, + @Nullable URI nodeUri, Instant timestamp, - Map payload) { + @Nullable Map payload) { this.sessionId = Require.nonNull("Session ID", sessionId); this.eventType = Require.nonNull("Event type", eventType); if (!eventType.matches("^[a-zA-Z][a-zA-Z0-9:._-]*$")) { @@ -133,10 +134,12 @@ public String getEventType() { return eventType; } + @Nullable public NodeId getNodeId() { return nodeId; } + @Nullable public URI getNodeUri() { return nodeUri; } @@ -165,6 +168,7 @@ public Object get(String key) { * @param key the key to look up * @return the string value, or null if not present or not a string */ + @Nullable public String getString(String key) { Object value = payload.get(key); return value instanceof String ? (String) value : null; @@ -212,7 +216,7 @@ private Map toJson() { return result; } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unused", "DataFlowIssue"}) private static SessionEventData fromJson(JsonInput input) { SessionId sessionId = null; String eventType = null; diff --git a/java/src/org/openqa/selenium/grid/data/SessionRemovalInfo.java b/java/src/org/openqa/selenium/grid/data/SessionRemovalInfo.java index 6cbe86e8af98b..353771724db06 100644 --- a/java/src/org/openqa/selenium/grid/data/SessionRemovalInfo.java +++ b/java/src/org/openqa/selenium/grid/data/SessionRemovalInfo.java @@ -20,13 +20,14 @@ import java.net.URI; import java.time.Duration; import java.time.Instant; +import org.jspecify.annotations.Nullable; public class SessionRemovalInfo { private final Instant removedAt; private final String reason; - private final URI nodeUri; + private final @Nullable URI nodeUri; - public SessionRemovalInfo(String reason, URI nodeUri) { + public SessionRemovalInfo(String reason, @Nullable URI nodeUri) { this.removedAt = Instant.now(); this.reason = reason; this.nodeUri = nodeUri; diff --git a/java/src/org/openqa/selenium/grid/data/SessionRequest.java b/java/src/org/openqa/selenium/grid/data/SessionRequest.java index aa299de2a8129..3cd4f5f7572e5 100644 --- a/java/src/org/openqa/selenium/grid/data/SessionRequest.java +++ b/java/src/org/openqa/selenium/grid/data/SessionRequest.java @@ -164,6 +164,7 @@ private Map toJson() { return unmodifiableMap(toReturn); } + @SuppressWarnings({"unused", "DataFlowIssue"}) private static SessionRequest fromJson(JsonInput input) { RequestId id = null; Instant enqueued = null; diff --git a/java/src/org/openqa/selenium/grid/data/SessionRequestCapability.java b/java/src/org/openqa/selenium/grid/data/SessionRequestCapability.java index 7091e57cd2b61..c86c7a3199896 100644 --- a/java/src/org/openqa/selenium/grid/data/SessionRequestCapability.java +++ b/java/src/org/openqa/selenium/grid/data/SessionRequestCapability.java @@ -17,11 +17,9 @@ package org.openqa.selenium.grid.data; -import static java.util.Collections.unmodifiableMap; import static java.util.Collections.unmodifiableSet; import java.lang.reflect.Type; -import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Objects; @@ -77,12 +75,10 @@ public int hashCode() { } private Map toJson() { - Map toReturn = new HashMap<>(); - toReturn.put("requestId", requestId); - toReturn.put("capabilities", desiredCapabilities); - return unmodifiableMap(toReturn); + return Map.of("requestId", requestId, "capabilities", desiredCapabilities); } + @SuppressWarnings({"unused", "DataFlowIssue"}) private static SessionRequestCapability fromJson(JsonInput input) { RequestId id = null; Set capabilities = null; diff --git a/java/src/org/openqa/selenium/grid/data/Slot.java b/java/src/org/openqa/selenium/grid/data/Slot.java index 938b8debb048e..007c109de6a94 100644 --- a/java/src/org/openqa/selenium/grid/data/Slot.java +++ b/java/src/org/openqa/selenium/grid/data/Slot.java @@ -24,6 +24,7 @@ import java.util.Map; import java.util.Objects; import java.util.TreeMap; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.Capabilities; import org.openqa.selenium.ImmutableCapabilities; import org.openqa.selenium.internal.Require; @@ -33,16 +34,17 @@ public class Slot implements Serializable { private final SlotId id; private final Capabilities stereotype; - private final Session session; + private final @Nullable Session session; private final Instant lastStarted; - public Slot(SlotId id, Capabilities stereotype, Instant lastStarted, Session session) { + public Slot(SlotId id, Capabilities stereotype, Instant lastStarted, @Nullable Session session) { this.id = Require.nonNull("Slot ID", id); this.stereotype = ImmutableCapabilities.copyOf(Require.nonNull("Stereotype", stereotype)); this.lastStarted = Require.nonNull("Last started", lastStarted); this.session = session; } + @SuppressWarnings({"unused", "DataFlowIssue"}) private static Slot fromJson(JsonInput input) { SlotId id = null; Capabilities stereotype = null; @@ -79,8 +81,8 @@ private static Slot fromJson(JsonInput input) { return new Slot(id, stereotype, lastStarted, session); } - private Map toJson() { - Map toReturn = new TreeMap<>(); + private Map toJson() { + Map toReturn = new TreeMap<>(); toReturn.put("id", getId()); toReturn.put("lastStarted", getLastStarted()); toReturn.put("session", getSession()); @@ -100,6 +102,7 @@ public Instant getLastStarted() { return lastStarted; } + @Nullable public Session getSession() { return session; } diff --git a/java/src/org/openqa/selenium/grid/data/SlotId.java b/java/src/org/openqa/selenium/grid/data/SlotId.java index 8a126e4071a01..20d4bbb9ce7ab 100644 --- a/java/src/org/openqa/selenium/grid/data/SlotId.java +++ b/java/src/org/openqa/selenium/grid/data/SlotId.java @@ -71,6 +71,7 @@ private Object toJson() { return unmodifiableMap(toReturn); } + @SuppressWarnings({"unused", "DataFlowIssue"}) private static SlotId fromJson(JsonInput input) { NodeId nodeId = null; UUID id = null; diff --git a/java/src/org/openqa/selenium/grid/data/package-info.java b/java/src/org/openqa/selenium/grid/data/package-info.java new file mode 100644 index 0000000000000..578785a87ff4c --- /dev/null +++ b/java/src/org/openqa/selenium/grid/data/package-info.java @@ -0,0 +1,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.grid.data; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/distributor/AddNode.java b/java/src/org/openqa/selenium/grid/distributor/AddNode.java index 904faaab6f1ec..4ca2e6d05528c 100644 --- a/java/src/org/openqa/selenium/grid/distributor/AddNode.java +++ b/java/src/org/openqa/selenium/grid/distributor/AddNode.java @@ -17,8 +17,6 @@ package org.openqa.selenium.grid.distributor; -import static org.openqa.selenium.remote.http.Contents.string; - import java.util.stream.Collectors; import org.openqa.selenium.grid.data.NodeStatus; import org.openqa.selenium.grid.data.Slot; @@ -56,7 +54,7 @@ class AddNode implements HttpHandler { @Override public HttpResponse execute(HttpRequest req) { - NodeStatus status = json.toType(string(req), NodeStatus.class); + NodeStatus status = json.toType(req.contentAsString(), NodeStatus.class); Node node = new RemoteNode( diff --git a/java/src/org/openqa/selenium/grid/distributor/BUILD.bazel b/java/src/org/openqa/selenium/grid/distributor/BUILD.bazel index ad61b54f26067..1e3fa9cdd4ec2 100644 --- a/java/src/org/openqa/selenium/grid/distributor/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/distributor/BUILD.bazel @@ -29,5 +29,6 @@ java_library( "//java/src/org/openqa/selenium/grid/sessionmap/remote", "//java/src/org/openqa/selenium/status", artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/distributor/GridModel.java b/java/src/org/openqa/selenium/grid/distributor/GridModel.java index b975a16082d94..382b030d68311 100644 --- a/java/src/org/openqa/selenium/grid/distributor/GridModel.java +++ b/java/src/org/openqa/selenium/grid/distributor/GridModel.java @@ -18,6 +18,7 @@ package org.openqa.selenium.grid.distributor; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.grid.data.Availability; import org.openqa.selenium.grid.data.NodeId; import org.openqa.selenium.grid.data.NodeStatus; @@ -101,7 +102,7 @@ public abstract class GridModel { * @param slotId The ID of the slot to update * @param session The session to associate with the slot, or null to clear */ - public abstract void setSession(SlotId slotId, Session session); + public abstract void setSession(SlotId slotId, @Nullable Session session); /** * Updates the health check count for a node based on its availability. diff --git a/java/src/org/openqa/selenium/grid/distributor/NodeRegistry.java b/java/src/org/openqa/selenium/grid/distributor/NodeRegistry.java index ec3ae18b7ee51..d56a71363b7a9 100644 --- a/java/src/org/openqa/selenium/grid/distributor/NodeRegistry.java +++ b/java/src/org/openqa/selenium/grid/distributor/NodeRegistry.java @@ -20,6 +20,7 @@ import java.io.Closeable; import java.net.URI; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.grid.data.Availability; import org.openqa.selenium.grid.data.DistributorStatus; import org.openqa.selenium.grid.data.NodeId; @@ -137,7 +138,7 @@ public interface NodeRegistry extends HasReadyState, Closeable { * @param slotId The slot ID. * @param session The session to associate with the slot, or null to clear. */ - void setSession(SlotId slotId, Session session); + void setSession(SlotId slotId, @Nullable Session session); /** Get the number of active slots. */ int getActiveSlots(); @@ -151,5 +152,5 @@ public interface NodeRegistry extends HasReadyState, Closeable { * @param uri The node URI to look up. * @return The node if found, null otherwise. */ - Node getNode(URI uri); + @Nullable Node getNode(URI uri); } diff --git a/java/src/org/openqa/selenium/grid/distributor/config/BUILD.bazel b/java/src/org/openqa/selenium/grid/distributor/config/BUILD.bazel index f75ae55ab7720..9170f39c8f6c2 100644 --- a/java/src/org/openqa/selenium/grid/distributor/config/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/distributor/config/BUILD.bazel @@ -15,5 +15,6 @@ java_library( "//java/src/org/openqa/selenium/grid/distributor/selector", "//java/src/org/openqa/selenium/grid/server", artifact("com.beust:jcommander"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/distributor/config/package-info.java b/java/src/org/openqa/selenium/grid/distributor/config/package-info.java new file mode 100644 index 0000000000000..7e9ae3048559a --- /dev/null +++ b/java/src/org/openqa/selenium/grid/distributor/config/package-info.java @@ -0,0 +1,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.grid.distributor.config; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/distributor/httpd/BUILD.bazel b/java/src/org/openqa/selenium/grid/distributor/httpd/BUILD.bazel index d538459e0b681..1d1b1c0934b0d 100644 --- a/java/src/org/openqa/selenium/grid/distributor/httpd/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/distributor/httpd/BUILD.bazel @@ -23,5 +23,6 @@ java_library( "//java/src/org/openqa/selenium/netty/server", artifact("com.beust:jcommander"), artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/distributor/httpd/package-info.java b/java/src/org/openqa/selenium/grid/distributor/httpd/package-info.java new file mode 100644 index 0000000000000..67ddea44d69dd --- /dev/null +++ b/java/src/org/openqa/selenium/grid/distributor/httpd/package-info.java @@ -0,0 +1,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.grid.distributor.httpd; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/distributor/local/BUILD.bazel b/java/src/org/openqa/selenium/grid/distributor/local/BUILD.bazel index 23552ec528410..c1af8f44e9aa1 100644 --- a/java/src/org/openqa/selenium/grid/distributor/local/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/distributor/local/BUILD.bazel @@ -31,5 +31,6 @@ java_library( "//java/src/org/openqa/selenium/json", "//java/src/org/openqa/selenium/remote", artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/distributor/local/LocalDistributor.java b/java/src/org/openqa/selenium/grid/distributor/local/LocalDistributor.java index 5a46acdfd93b1..c888c5a0b836e 100644 --- a/java/src/org/openqa/selenium/grid/distributor/local/LocalDistributor.java +++ b/java/src/org/openqa/selenium/grid/distributor/local/LocalDistributor.java @@ -50,6 +50,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.Beta; import org.openqa.selenium.Capabilities; import org.openqa.selenium.ImmutableCapabilities; @@ -448,6 +449,7 @@ private CreateSessionResponse startSession( return result.right(); } + @Nullable private SlotId reserveSlot(RequestId requestId, Capabilities caps) { // Use read lock for slot selection to allow concurrent reads // This reduces contention compared to using write lock for the entire operation @@ -679,6 +681,7 @@ private void handleNewSessionRequest(SessionRequest sessionRequest) { } } + @Nullable protected Node getNodeFromURI(URI uri) { Lock readLock = this.lock.readLock(); readLock.lock(); diff --git a/java/src/org/openqa/selenium/grid/distributor/local/LocalGridModel.java b/java/src/org/openqa/selenium/grid/distributor/local/LocalGridModel.java index cf4985b299b0a..15d271ae8f706 100644 --- a/java/src/org/openqa/selenium/grid/distributor/local/LocalGridModel.java +++ b/java/src/org/openqa/selenium/grid/distributor/local/LocalGridModel.java @@ -34,6 +34,7 @@ import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.logging.Logger; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.events.EventBus; import org.openqa.selenium.grid.config.Config; import org.openqa.selenium.grid.data.Availability; @@ -169,7 +170,7 @@ public void refresh(NodeStatus status) { if (node.getNodeId().equals(status.getNodeId())) { iterator.remove(); - // if the node was marked as "down", keep it down until a healthcheck passes: + // if the node was marked as "down", keep it down until a health check passes: // just because the node can hit the event bus doesn't mean it's reachable if (node.getAvailability() == DOWN) { nodes.add(rewrite(status, DOWN)); @@ -375,6 +376,7 @@ public Set getSnapshot() { } } + @Nullable private NodeStatus getNode(NodeId id) { Require.nonNull("Node ID", id); @@ -401,7 +403,7 @@ private NodeStatus rewrite(NodeStatus status, Availability availability) { } @Override - public void release(SessionId id) { + public void release(@Nullable SessionId id) { if (id == null) { return; } @@ -430,7 +432,7 @@ public void release(SessionId id) { } @Override - public void setSession(SlotId slotId, Session session) { + public void setSession(SlotId slotId, @Nullable Session session) { Require.nonNull("Slot ID", slotId); Lock writeLock = lock.writeLock(); diff --git a/java/src/org/openqa/selenium/grid/distributor/local/LocalNodeRegistry.java b/java/src/org/openqa/selenium/grid/distributor/local/LocalNodeRegistry.java index 77612fae8aaea..bcd21fc1675d0 100644 --- a/java/src/org/openqa/selenium/grid/distributor/local/LocalNodeRegistry.java +++ b/java/src/org/openqa/selenium/grid/distributor/local/LocalNodeRegistry.java @@ -46,6 +46,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.HealthCheckFailedException; import org.openqa.selenium.concurrent.GuardedRunnable; import org.openqa.selenium.events.EventBus; @@ -519,7 +520,7 @@ public boolean reserve(SlotId slotId) { } @Override - public void setSession(SlotId slotId, Session session) { + public void setSession(SlotId slotId, @Nullable Session session) { Lock writeLock = lock.writeLock(); writeLock.lock(); try { @@ -565,6 +566,7 @@ public int getIdleSlots() { * @param uri The URI of the node to find * @return The node if found, null otherwise */ + @Nullable public Node getNode(URI uri) { Lock readLock = this.lock.readLock(); readLock.lock(); diff --git a/java/src/org/openqa/selenium/grid/distributor/local/package-info.java b/java/src/org/openqa/selenium/grid/distributor/local/package-info.java new file mode 100644 index 0000000000000..29ed00ad32e30 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/distributor/local/package-info.java @@ -0,0 +1,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.grid.distributor.local; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/distributor/package-info.java b/java/src/org/openqa/selenium/grid/distributor/package-info.java index 10f446636bfd2..afd36d731e800 100644 --- a/java/src/org/openqa/selenium/grid/distributor/package-info.java +++ b/java/src/org/openqa/selenium/grid/distributor/package-info.java @@ -27,4 +27,7 @@ * that dialects match, or that a converter of some sort is added. The Node may be the part of the * system responsible for adding this converter. */ +@NullMarked package org.openqa.selenium.grid.distributor; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/distributor/remote/BUILD.bazel b/java/src/org/openqa/selenium/grid/distributor/remote/BUILD.bazel index 53ebc5ce3f192..949a8d397b31f 100644 --- a/java/src/org/openqa/selenium/grid/distributor/remote/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/distributor/remote/BUILD.bazel @@ -1,3 +1,4 @@ +load("@rules_jvm_external//:defs.bzl", "artifact") load("//java:defs.bzl", "java_library") java_library( @@ -17,5 +18,6 @@ java_library( "//java/src/org/openqa/selenium/grid/sessionmap", "//java/src/org/openqa/selenium/grid/web", "//java/src/org/openqa/selenium/remote", + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/distributor/remote/package-info.java b/java/src/org/openqa/selenium/grid/distributor/remote/package-info.java new file mode 100644 index 0000000000000..7a6aaf0fa411c --- /dev/null +++ b/java/src/org/openqa/selenium/grid/distributor/remote/package-info.java @@ -0,0 +1,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.grid.distributor.remote; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/distributor/selector/BUILD.bazel b/java/src/org/openqa/selenium/grid/distributor/selector/BUILD.bazel index 867ab5082ec90..a1ade3769a079 100644 --- a/java/src/org/openqa/selenium/grid/distributor/selector/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/distributor/selector/BUILD.bazel @@ -13,5 +13,6 @@ java_library( "//java/src/org/openqa/selenium/grid/config", "//java/src/org/openqa/selenium/grid/data", artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/distributor/selector/package-info.java b/java/src/org/openqa/selenium/grid/distributor/selector/package-info.java new file mode 100644 index 0000000000000..0344710f634c2 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/distributor/selector/package-info.java @@ -0,0 +1,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.grid.distributor.selector; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/graphql/BUILD.bazel b/java/src/org/openqa/selenium/grid/graphql/BUILD.bazel index a9a9c0a7b5953..102f20a1987fe 100644 --- a/java/src/org/openqa/selenium/grid/graphql/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/graphql/BUILD.bazel @@ -22,5 +22,6 @@ java_library( artifact("com.google.guava:guava"), artifact("com.graphql-java:graphql-java"), artifact("com.github.ben-manes.caffeine:caffeine"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/graphql/SessionData.java b/java/src/org/openqa/selenium/grid/graphql/SessionData.java index 94396fbd2f942..92bc288d58aaa 100644 --- a/java/src/org/openqa/selenium/grid/graphql/SessionData.java +++ b/java/src/org/openqa/selenium/grid/graphql/SessionData.java @@ -20,6 +20,7 @@ import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.grid.data.NodeStatus; import org.openqa.selenium.grid.data.Slot; import org.openqa.selenium.grid.distributor.Distributor; @@ -62,6 +63,7 @@ public org.openqa.selenium.grid.graphql.Session get(DataFetchingEnvironment envi } } + @Nullable private SessionInSlot findSession(String sessionId, Set nodeStatuses) { for (NodeStatus status : nodeStatuses) { for (Slot slot : status.getSlots()) { diff --git a/java/src/org/openqa/selenium/grid/graphql/Types.java b/java/src/org/openqa/selenium/grid/graphql/Types.java index 5bb2a21fa2b1a..da1857d3e0113 100644 --- a/java/src/org/openqa/selenium/grid/graphql/Types.java +++ b/java/src/org/openqa/selenium/grid/graphql/Types.java @@ -27,6 +27,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import org.jspecify.annotations.Nullable; class Types { @@ -53,10 +54,6 @@ public String serialize(Object o) throws CoercingSerializeException { @Override public URI parseValue(Object input) throws CoercingParseValueException { - if (input == null) { - return null; - } - if (input instanceof URI) { return (URI) input; } @@ -110,8 +107,9 @@ public String serialize(Object o) throws CoercingSerializeException { throw new CoercingSerializeException("Unable to coerce " + o); } + @Nullable @Override - public URL parseValue(Object input) throws CoercingParseValueException { + public URL parseValue(@Nullable Object input) throws CoercingParseValueException { if (input == null) { return null; } diff --git a/java/src/org/openqa/selenium/grid/graphql/package-info.java b/java/src/org/openqa/selenium/grid/graphql/package-info.java new file mode 100644 index 0000000000000..df07cd66175e3 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/graphql/package-info.java @@ -0,0 +1,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.grid.graphql; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/jmx/JMXHelper.java b/java/src/org/openqa/selenium/grid/jmx/JMXHelper.java index 54b8644eec577..8dd73bd8ecd37 100644 --- a/java/src/org/openqa/selenium/grid/jmx/JMXHelper.java +++ b/java/src/org/openqa/selenium/grid/jmx/JMXHelper.java @@ -22,10 +22,8 @@ import javax.management.InstanceAlreadyExistsException; import javax.management.MBeanServer; import javax.management.ObjectName; -import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; -@NullMarked public class JMXHelper { private static final Logger LOG = Logger.getLogger(JMXHelper.class.getName()); @@ -44,7 +42,7 @@ public class JMXHelper { } } - public void unregister(ObjectName objectName) { + public void unregister(@Nullable ObjectName objectName) { if (objectName != null) { MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); try { diff --git a/java/src/org/openqa/selenium/grid/jmx/MBean.java b/java/src/org/openqa/selenium/grid/jmx/MBean.java index dce77f1da0746..3a7c7511e9a33 100644 --- a/java/src/org/openqa/selenium/grid/jmx/MBean.java +++ b/java/src/org/openqa/selenium/grid/jmx/MBean.java @@ -99,7 +99,7 @@ MBeanOperationInfo getMBeanOperationInfo() { String name = bean.getClass().getName(); String description = mBean.description(); collectAttributeInfo(bean); - MBeanAttributeInfo[] attributes = + @Nullable MBeanAttributeInfo[] attributes = attributeMap.values().stream() .map(AttributeInfo::getMBeanAttributeInfo) .toArray(MBeanAttributeInfo[]::new); @@ -254,7 +254,7 @@ public void setAttribute(Attribute attribute) { } @Override - public AttributeList getAttributes(String[] attributes) { + public AttributeList getAttributes(String @Nullable [] attributes) { AttributeList resultList = new AttributeList(); // if attributeNames is empty, return an empty result list diff --git a/java/src/org/openqa/selenium/grid/jmx/package-info.java b/java/src/org/openqa/selenium/grid/jmx/package-info.java new file mode 100644 index 0000000000000..51159a8e5004d --- /dev/null +++ b/java/src/org/openqa/selenium/grid/jmx/package-info.java @@ -0,0 +1,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.grid.jmx; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/log/BUILD.bazel b/java/src/org/openqa/selenium/grid/log/BUILD.bazel index a8d998a81e209..68c796f96396b 100644 --- a/java/src/org/openqa/selenium/grid/log/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/log/BUILD.bazel @@ -14,5 +14,6 @@ java_library( "//java/src/org/openqa/selenium/json", "//java/src/org/openqa/selenium/remote", artifact("com.beust:jcommander"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/log/FlushingHandler.java b/java/src/org/openqa/selenium/grid/log/FlushingHandler.java index 8adda6023719c..b556231dcbbd6 100644 --- a/java/src/org/openqa/selenium/grid/log/FlushingHandler.java +++ b/java/src/org/openqa/selenium/grid/log/FlushingHandler.java @@ -21,10 +21,11 @@ import java.util.Objects; import java.util.logging.LogRecord; import java.util.logging.StreamHandler; +import org.jspecify.annotations.Nullable; class FlushingHandler extends StreamHandler { - private OutputStream out; + @Nullable private OutputStream out; FlushingHandler(OutputStream out) { setOutputStream(out); diff --git a/java/src/org/openqa/selenium/grid/log/LoggingOptions.java b/java/src/org/openqa/selenium/grid/log/LoggingOptions.java index 20cb5a770e68a..b812bac69f186 100644 --- a/java/src/org/openqa/selenium/grid/log/LoggingOptions.java +++ b/java/src/org/openqa/selenium/grid/log/LoggingOptions.java @@ -30,6 +30,7 @@ import java.util.logging.Level; import java.util.logging.LogManager; import java.util.logging.Logger; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.grid.config.Config; import org.openqa.selenium.grid.config.ConfigException; import org.openqa.selenium.internal.Debug; @@ -79,6 +80,7 @@ public boolean isUsingPlainLogs() { return config.getBool(LOGGING_SECTION, "plain-logs").orElse(DEFAULT_PLAIN_LOGS); } + @Nullable public String getLogEncoding() { return config.get(LOGGING_SECTION, "log-encoding").orElse(null); } @@ -169,7 +171,7 @@ public void configureLogging() { } } - private void configureLogEncoding(Logger logger, String encoding, Handler handler) { + private void configureLogEncoding(Logger logger, @Nullable String encoding, Handler handler) { String message; try { if (encoding != null) { diff --git a/java/src/org/openqa/selenium/grid/log/package-info.java b/java/src/org/openqa/selenium/grid/log/package-info.java new file mode 100644 index 0000000000000..fd4c74b6d998a --- /dev/null +++ b/java/src/org/openqa/selenium/grid/log/package-info.java @@ -0,0 +1,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.grid.log; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/node/Node.java b/java/src/org/openqa/selenium/grid/node/Node.java index 1d933e33c6c6a..8171a0f753d75 100644 --- a/java/src/org/openqa/selenium/grid/node/Node.java +++ b/java/src/org/openqa/selenium/grid/node/Node.java @@ -35,6 +35,7 @@ import java.util.logging.Logger; import java.util.stream.Collectors; import java.util.stream.StreamSupport; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.BuildInfo; import org.openqa.selenium.Capabilities; import org.openqa.selenium.NoSuchSessionException; @@ -255,8 +256,10 @@ public TemporaryFilesystem getDownloadsFilesystem(SessionId id) throws IOExcepti throw new UnsupportedOperationException(); } + @Nullable public abstract HttpResponse uploadFile(HttpRequest req, SessionId id); + @Nullable public abstract HttpResponse downloadFile(HttpRequest req, SessionId id); /** diff --git a/java/src/org/openqa/selenium/grid/node/config/BUILD.bazel b/java/src/org/openqa/selenium/grid/node/config/BUILD.bazel index d71932bada408..6c747672982fe 100644 --- a/java/src/org/openqa/selenium/grid/node/config/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/node/config/BUILD.bazel @@ -19,5 +19,6 @@ java_library( "//java/src/org/openqa/selenium/remote", artifact("com.beust:jcommander"), artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/node/config/DriverServiceSessionFactory.java b/java/src/org/openqa/selenium/grid/node/config/DriverServiceSessionFactory.java index 3a1b8aa09f2de..14a74962fdc6d 100644 --- a/java/src/org/openqa/selenium/grid/node/config/DriverServiceSessionFactory.java +++ b/java/src/org/openqa/selenium/grid/node/config/DriverServiceSessionFactory.java @@ -35,6 +35,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.Capabilities; import org.openqa.selenium.ImmutableCapabilities; import org.openqa.selenium.MutableCapabilities; @@ -324,6 +325,7 @@ private Capabilities setInitialCapabilityValue(Capabilities caps, String key, Ob return new PersistentCapabilities(caps).setCapability(key, value); } + @Nullable private String getHost() { try { return new NetworkUtils().getNonLoopbackAddressOfThisMachine(); diff --git a/java/src/org/openqa/selenium/grid/node/config/NodeOptions.java b/java/src/org/openqa/selenium/grid/node/config/NodeOptions.java index 23c4616039dff..be9cf1f76d08c 100644 --- a/java/src/org/openqa/selenium/grid/node/config/NodeOptions.java +++ b/java/src/org/openqa/selenium/grid/node/config/NodeOptions.java @@ -803,7 +803,7 @@ private void report(Map.Entry> entry) private String unquote(String input) { int len = input.length(); if ((input.charAt(0) == '"') && (input.charAt(len - 1) == '"')) { - return new Json().newInput(new StringReader(input)).read(Json.OBJECT_TYPE); + return new Json().newInput(new StringReader(input)).readNonNull(Json.OBJECT_TYPE); } return input; } diff --git a/java/src/org/openqa/selenium/grid/node/config/SessionCapabilitiesMutator.java b/java/src/org/openqa/selenium/grid/node/config/SessionCapabilitiesMutator.java index 1d3431d779ab4..89fcf5c58b017 100644 --- a/java/src/org/openqa/selenium/grid/node/config/SessionCapabilitiesMutator.java +++ b/java/src/org/openqa/selenium/grid/node/config/SessionCapabilitiesMutator.java @@ -27,6 +27,7 @@ import org.openqa.selenium.Capabilities; import org.openqa.selenium.ImmutableCapabilities; import org.openqa.selenium.PersistentCapabilities; +import org.openqa.selenium.internal.Require; public class SessionCapabilitiesMutator implements Function { @@ -49,11 +50,13 @@ public Capabilities apply(Capabilities capabilities) { return capabilities; } - if (slotStereotype.getCapability(SE_VNC_ENABLED) != null) { + Object vncEnabled = slotStereotype.getCapability(SE_VNC_ENABLED); + if (vncEnabled != null) { + Object vncPort = slotStereotype.getCapability(SE_NO_VNC_PORT); capabilities = new PersistentCapabilities(capabilities) - .setCapability(SE_VNC_ENABLED, slotStereotype.getCapability(SE_VNC_ENABLED)) - .setCapability(SE_NO_VNC_PORT, slotStereotype.getCapability(SE_NO_VNC_PORT)); + .setCapability(SE_VNC_ENABLED, vncEnabled) + .setCapability(SE_NO_VNC_PORT, Require.nonNull(SE_NO_VNC_PORT, vncPort)); } String browserName = capabilities.getBrowserName().toLowerCase(Locale.ENGLISH); diff --git a/java/src/org/openqa/selenium/grid/node/config/package-info.java b/java/src/org/openqa/selenium/grid/node/config/package-info.java new file mode 100644 index 0000000000000..51df08ff26d59 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/node/config/package-info.java @@ -0,0 +1,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.grid.node.config; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/node/docker/BUILD.bazel b/java/src/org/openqa/selenium/grid/node/docker/BUILD.bazel index 6cc6de13f6695..a4e1467776f4c 100644 --- a/java/src/org/openqa/selenium/grid/node/docker/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/node/docker/BUILD.bazel @@ -22,5 +22,6 @@ java_library( "//java/src/org/openqa/selenium/support", artifact("com.beust:jcommander"), artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/node/docker/DockerOptions.java b/java/src/org/openqa/selenium/grid/node/docker/DockerOptions.java index d95363d8e9502..ce422300835a2 100644 --- a/java/src/org/openqa/selenium/grid/node/docker/DockerOptions.java +++ b/java/src/org/openqa/selenium/grid/node/docker/DockerOptions.java @@ -37,6 +37,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.Capabilities; import org.openqa.selenium.Platform; import org.openqa.selenium.docker.ContainerId; @@ -115,6 +116,7 @@ private Duration getServerStartTimeout() { config.getInt(DOCKER_SECTION, "server-start-timeout").orElse(DEFAULT_SERVER_START_TIMEOUT)); } + @Nullable private String getApiVersion() { return config.get(DOCKER_SECTION, "api-version").orElse(null); } @@ -238,6 +240,7 @@ protected List getDevicesMapping() { return deviceMapping; } + @Nullable private Image getVideoImage(Docker docker) { String videoImage = config.get(DOCKER_SECTION, "video-image").orElse(DEFAULT_VIDEO_IMAGE); if (videoImage.equalsIgnoreCase("false")) { @@ -280,6 +283,7 @@ private Map getGroupingLabels(Optional info) { .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); } + @Nullable @SuppressWarnings("OptionalUsedAsFieldOrParameterType") private DockerAssetsPath getAssetsPath(Optional info) { if (info.isPresent()) { diff --git a/java/src/org/openqa/selenium/grid/node/docker/DockerSession.java b/java/src/org/openqa/selenium/grid/node/docker/DockerSession.java index 6608e7cb7bdca..464be03e2ab5d 100644 --- a/java/src/org/openqa/selenium/grid/node/docker/DockerSession.java +++ b/java/src/org/openqa/selenium/grid/node/docker/DockerSession.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.Capabilities; import org.openqa.selenium.docker.Container; import org.openqa.selenium.grid.node.DefaultActiveSession; @@ -38,12 +39,12 @@ public class DockerSession extends DefaultActiveSession { private static final Logger LOG = Logger.getLogger(DockerSession.class.getName()); private final Container container; - private final Container videoContainer; + private final @Nullable Container videoContainer; private final DockerAssetsPath assetsPath; DockerSession( Container container, - Container videoContainer, + @Nullable Container videoContainer, Tracer tracer, HttpClient client, SessionId id, diff --git a/java/src/org/openqa/selenium/grid/node/docker/DockerSessionFactory.java b/java/src/org/openqa/selenium/grid/node/docker/DockerSessionFactory.java index 9aef964df9246..189275b166240 100644 --- a/java/src/org/openqa/selenium/grid/node/docker/DockerSessionFactory.java +++ b/java/src/org/openqa/selenium/grid/node/docker/DockerSessionFactory.java @@ -20,7 +20,6 @@ import static java.util.Optional.ofNullable; import static org.openqa.selenium.docker.ContainerConfig.image; import static org.openqa.selenium.remote.Dialect.W3C; -import static org.openqa.selenium.remote.http.Contents.string; import static org.openqa.selenium.remote.http.HttpMethod.GET; import static org.openqa.selenium.remote.tracing.Tags.EXCEPTION; @@ -44,6 +43,7 @@ import java.util.function.Predicate; import java.util.logging.Level; import java.util.logging.Logger; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.Capabilities; import org.openqa.selenium.Dimension; import org.openqa.selenium.ImmutableCapabilities; @@ -98,8 +98,8 @@ public class DockerSessionFactory implements SessionFactory { private final Image browserImage; private final Capabilities stereotype; private final List devices; - private final Image videoImage; - private final DockerAssetsPath assetsPath; + private final @Nullable Image videoImage; + private final @Nullable DockerAssetsPath assetsPath; private final String networkName; private final boolean runningInDocker; private final Predicate predicate; @@ -117,8 +117,8 @@ public DockerSessionFactory( Image browserImage, Capabilities stereotype, List devices, - Image videoImage, - DockerAssetsPath assetsPath, + @Nullable Image videoImage, + @Nullable DockerAssetsPath assetsPath, String networkName, boolean runningInDocker, Predicate predicate, @@ -162,7 +162,7 @@ public Either apply(CreateSessionRequest sess // Generate unique identifier for consistent naming between browser and recorder containers // Using browserName-timestamp-UUID to avoid conflicts in concurrent session creation String browserName = sessionRequest.getDesiredCapabilities().getBrowserName(); - if (browserName != null && !browserName.isEmpty()) { + if (!browserName.isEmpty()) { browserName = browserName.toLowerCase(); } else { browserName = "unknown"; @@ -374,6 +374,7 @@ private void setCapsToEnvVars( timeZone.ifPresent(zone -> envVars.put("TZ", zone.getID())); } + @Nullable private Container startVideoContainer( Capabilities sessionCapabilities, String browserContainerIp, @@ -438,6 +439,7 @@ private Map getVideoContainerEnvVars( return envVars; } + @Nullable private String getVideoFileName(Capabilities sessionRequestCapabilities, String capabilityName) { Optional testName = ofNullable(sessionRequestCapabilities.getCapability(capabilityName)); @@ -454,6 +456,7 @@ private String getVideoFileName(Capabilities sessionRequestCapabilities, String return null; } + @Nullable private TimeZone getTimeZone(Capabilities sessionRequestCapabilities) { Optional timeZone = ofNullable(sessionRequestCapabilities.getCapability("se:timeZone")); if (timeZone.isPresent()) { @@ -469,6 +472,7 @@ private TimeZone getTimeZone(Capabilities sessionRequestCapabilities) { return null; } + @Nullable private Dimension getScreenResolution(Capabilities sessionRequestCapabilities) { Optional screenResolution = ofNullable(sessionRequestCapabilities.getCapability("se:screenResolution")); @@ -521,7 +525,7 @@ private void waitForServerToStart(HttpClient client, Duration duration) { wait.until( obj -> { HttpResponse response = client.execute(new HttpRequest(GET, "/status")); - LOG.fine(string(response)); + LOG.fine(response::contentAsString); if (401 == response.getStatus()) { LOG.warning( "Server requires basic authentication. " diff --git a/java/src/org/openqa/selenium/grid/node/docker/package-info.java b/java/src/org/openqa/selenium/grid/node/docker/package-info.java new file mode 100644 index 0000000000000..b2e9f6b6b6b1b --- /dev/null +++ b/java/src/org/openqa/selenium/grid/node/docker/package-info.java @@ -0,0 +1,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.grid.node.docker; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/node/httpd/BUILD.bazel b/java/src/org/openqa/selenium/grid/node/httpd/BUILD.bazel index 605d9a02092d0..04bcc32571c75 100644 --- a/java/src/org/openqa/selenium/grid/node/httpd/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/node/httpd/BUILD.bazel @@ -24,5 +24,6 @@ java_library( "//java/src/org/openqa/selenium/remote", artifact("com.google.guava:guava"), artifact("dev.failsafe:failsafe"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/node/httpd/NodeServer.java b/java/src/org/openqa/selenium/grid/node/httpd/NodeServer.java index dd93d481b4f7d..a69044b822575 100644 --- a/java/src/org/openqa/selenium/grid/node/httpd/NodeServer.java +++ b/java/src/org/openqa/selenium/grid/node/httpd/NodeServer.java @@ -38,6 +38,7 @@ import java.util.concurrent.Executors; import java.util.logging.Level; import java.util.logging.Logger; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.BuildInfo; import org.openqa.selenium.cli.CliCommand; import org.openqa.selenium.events.EventBus; @@ -72,8 +73,8 @@ public class NodeServer extends TemplateGridServerCommand { private static final Logger LOG = Logger.getLogger(NodeServer.class.getName()); - private Node node; - private EventBus bus; + private @Nullable Node node; + private @Nullable EventBus bus; private final Thread shutdownHook = new Thread(() -> bus.fire(new NodeRemovedEvent(node.getStatus()))); diff --git a/java/src/org/openqa/selenium/grid/node/httpd/package-info.java b/java/src/org/openqa/selenium/grid/node/httpd/package-info.java new file mode 100644 index 0000000000000..e1c8b8d14cf0b --- /dev/null +++ b/java/src/org/openqa/selenium/grid/node/httpd/package-info.java @@ -0,0 +1,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.grid.node.httpd; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/node/k8s/BUILD.bazel b/java/src/org/openqa/selenium/grid/node/k8s/BUILD.bazel index 68b5f9cd50cc0..e78639b6c9eef 100644 --- a/java/src/org/openqa/selenium/grid/node/k8s/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/node/k8s/BUILD.bazel @@ -14,5 +14,6 @@ java_library( "//java/src/org/openqa/selenium/remote", artifact("com.beust:jcommander"), artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/node/k8s/OneShotNode.java b/java/src/org/openqa/selenium/grid/node/k8s/OneShotNode.java index 1281083a0970c..a0ebc6848d71d 100644 --- a/java/src/org/openqa/selenium/grid/node/k8s/OneShotNode.java +++ b/java/src/org/openqa/selenium/grid/node/k8s/OneShotNode.java @@ -39,6 +39,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.StreamSupport; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.Capabilities; import org.openqa.selenium.ImmutableCapabilities; import org.openqa.selenium.NoSuchSessionException; @@ -106,10 +107,10 @@ public class OneShotNode extends Node { private final UUID slotId = UUID.randomUUID(); private final int connectionLimitPerSession; private final AtomicInteger connectionCounter = new AtomicInteger(); - private RemoteWebDriver driver; - private SessionId sessionId; - private HttpClient client; - private Capabilities capabilities; + private @Nullable RemoteWebDriver driver; + private @Nullable SessionId sessionId; + private @Nullable HttpClient client; + private @Nullable Capabilities capabilities; private Instant sessionStart = Instant.EPOCH; private OneShotNode( @@ -264,6 +265,7 @@ private HttpClient extractHttpClient(RemoteWebDriver driver) { } } + @Nullable private Field findClientField(Class clazz) { try { return clazz.getDeclaredField("client"); @@ -334,11 +336,13 @@ public Session getSession(SessionId id) throws NoSuchSessionException { return new Session(sessionId, getUri(), stereotype, capabilities, sessionStart); } + @Nullable @Override public HttpResponse uploadFile(HttpRequest req, SessionId id) { return null; } + @Nullable @Override public HttpResponse downloadFile(HttpRequest req, SessionId id) { return null; diff --git a/java/src/org/openqa/selenium/grid/node/k8s/package-info.java b/java/src/org/openqa/selenium/grid/node/k8s/package-info.java new file mode 100644 index 0000000000000..645e3b9df98d8 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/node/k8s/package-info.java @@ -0,0 +1,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.grid.node.k8s; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/node/kubernetes/BUILD.bazel b/java/src/org/openqa/selenium/grid/node/kubernetes/BUILD.bazel index 54641b1b7924e..bef0936b08149 100644 --- a/java/src/org/openqa/selenium/grid/node/kubernetes/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/node/kubernetes/BUILD.bazel @@ -38,6 +38,7 @@ java_export( artifact("io.fabric8:kubernetes-client-api"), artifact("io.fabric8:kubernetes-model-batch"), artifact("io.fabric8:kubernetes-model-core"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/node/kubernetes/InheritedPodSpec.java b/java/src/org/openqa/selenium/grid/node/kubernetes/InheritedPodSpec.java index 827a10b0e35cc..ebd5e07694f5e 100644 --- a/java/src/org/openqa/selenium/grid/node/kubernetes/InheritedPodSpec.java +++ b/java/src/org/openqa/selenium/grid/node/kubernetes/InheritedPodSpec.java @@ -26,43 +26,44 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import org.jspecify.annotations.Nullable; public class InheritedPodSpec { private final List tolerations; - private final Affinity affinity; + private final @Nullable Affinity affinity; private final List imagePullSecrets; - private final String dnsPolicy; - private final PodDNSConfig dnsConfig; - private final PodSecurityContext securityContext; - private final String priorityClassName; + private final @Nullable String dnsPolicy; + private final @Nullable PodDNSConfig dnsConfig; + private final @Nullable PodSecurityContext securityContext; + private final @Nullable String priorityClassName; private final Map nodeSelector; - private final String serviceAccountName; + private final @Nullable String serviceAccountName; private final Map labels; private final Map annotations; - private final String imagePullPolicy; + private final @Nullable String imagePullPolicy; private final Map resourceRequests; private final Map resourceLimits; - private final String assetsClaimName; - private final String nodePodName; - private final String nodePodUid; + private final @Nullable String assetsClaimName; + private final @Nullable String nodePodName; + private final @Nullable String nodePodUid; public InheritedPodSpec( - List tolerations, - Affinity affinity, - List imagePullSecrets, - String dnsPolicy, - PodDNSConfig dnsConfig, - PodSecurityContext securityContext, - String priorityClassName, - Map nodeSelector, - String serviceAccountName, - Map labels, - Map annotations, - String imagePullPolicy, - Map resourceRequests, - Map resourceLimits, - String assetsClaimName) { + @Nullable List tolerations, + @Nullable Affinity affinity, + @Nullable List imagePullSecrets, + @Nullable String dnsPolicy, + @Nullable PodDNSConfig dnsConfig, + @Nullable PodSecurityContext securityContext, + @Nullable String priorityClassName, + @Nullable Map nodeSelector, + @Nullable String serviceAccountName, + @Nullable Map labels, + @Nullable Map annotations, + @Nullable String imagePullPolicy, + @Nullable Map resourceRequests, + @Nullable Map resourceLimits, + @Nullable String assetsClaimName) { this( tolerations, affinity, @@ -84,23 +85,23 @@ public InheritedPodSpec( } public InheritedPodSpec( - List tolerations, - Affinity affinity, - List imagePullSecrets, - String dnsPolicy, - PodDNSConfig dnsConfig, - PodSecurityContext securityContext, - String priorityClassName, - Map nodeSelector, - String serviceAccountName, - Map labels, - Map annotations, - String imagePullPolicy, - Map resourceRequests, - Map resourceLimits, - String assetsClaimName, - String nodePodName, - String nodePodUid) { + @Nullable List tolerations, + @Nullable Affinity affinity, + @Nullable List imagePullSecrets, + @Nullable String dnsPolicy, + @Nullable PodDNSConfig dnsConfig, + @Nullable PodSecurityContext securityContext, + @Nullable String priorityClassName, + @Nullable Map nodeSelector, + @Nullable String serviceAccountName, + @Nullable Map labels, + @Nullable Map annotations, + @Nullable String imagePullPolicy, + @Nullable Map resourceRequests, + @Nullable Map resourceLimits, + @Nullable String assetsClaimName, + @Nullable String nodePodName, + @Nullable String nodePodUid) { this.tolerations = tolerations != null ? List.copyOf(tolerations) : List.of(); this.affinity = affinity; this.imagePullSecrets = imagePullSecrets != null ? List.copyOf(imagePullSecrets) : List.of(); @@ -150,6 +151,7 @@ public List getTolerations() { return tolerations; } + @Nullable public Affinity getAffinity() { return affinity; } @@ -158,18 +160,22 @@ public List getImagePullSecrets() { return imagePullSecrets; } + @Nullable public String getDnsPolicy() { return dnsPolicy; } + @Nullable public PodDNSConfig getDnsConfig() { return dnsConfig; } + @Nullable public PodSecurityContext getSecurityContext() { return securityContext; } + @Nullable public String getPriorityClassName() { return priorityClassName; } @@ -178,6 +184,7 @@ public Map getNodeSelector() { return nodeSelector; } + @Nullable public String getServiceAccountName() { return serviceAccountName; } @@ -190,6 +197,7 @@ public Map getAnnotations() { return annotations; } + @Nullable public String getImagePullPolicy() { return imagePullPolicy; } @@ -202,6 +210,7 @@ public Map getResourceLimits() { return resourceLimits; } + @Nullable public String getAssetsClaimName() { return assetsClaimName; } @@ -213,10 +222,12 @@ public boolean hasNodePodOwnerReference() { && !nodePodUid.isEmpty(); } + @Nullable public String getNodePodName() { return nodePodName; } + @Nullable public String getNodePodUid() { return nodePodUid; } diff --git a/java/src/org/openqa/selenium/grid/node/kubernetes/KubernetesOptions.java b/java/src/org/openqa/selenium/grid/node/kubernetes/KubernetesOptions.java index cb25d7f57792e..de032983ec704 100644 --- a/java/src/org/openqa/selenium/grid/node/kubernetes/KubernetesOptions.java +++ b/java/src/org/openqa/selenium/grid/node/kubernetes/KubernetesOptions.java @@ -41,6 +41,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.Capabilities; import org.openqa.selenium.grid.config.ConfigException; import org.openqa.selenium.grid.node.SessionFactory; @@ -320,7 +321,7 @@ String getNamespace() { return getNamespace(null); } - String getNamespace(KubernetesClient kubeClient) { + String getNamespace(@Nullable KubernetesClient kubeClient) { // Priority: config → client auto-detected namespace → "default" // The fabric8 KubernetesClient.getNamespace() already reads from kubeconfig, // in-cluster service account namespace file, and KUBERNETES_NAMESPACE env var. @@ -366,6 +367,7 @@ Map getNodeSelector() { return parseKeyValueMap(config.get(K8S_SECTION, "node-selector").orElse(null)); } + @Nullable private String getVideoImage() { String image = config.get(K8S_SECTION, "video-image").orElse(DEFAULT_VIDEO_IMAGE); if (image.equalsIgnoreCase("false")) { @@ -374,6 +376,7 @@ private String getVideoImage() { return image; } + @Nullable private String getAssetsPath() { return config.get(K8S_SECTION, "assets-path").orElse(null); } @@ -388,7 +391,10 @@ boolean isRunningInKubernetes() { } InheritedPodSpec inspectNodePod( - KubernetesClient kubeClient, String namespace, String labelInheritPrefix, String assetsPath) { + KubernetesClient kubeClient, + String namespace, + String labelInheritPrefix, + @Nullable String assetsPath) { if (!isRunningInKubernetes()) { LOG.fine("Not running in Kubernetes; skipping Node Pod inspection"); return InheritedPodSpec.empty(); @@ -496,7 +502,8 @@ InheritedPodSpec inspectNodePod( } } - static Map filterByPrefix(Map map, String prefix) { + static Map filterByPrefix( + @Nullable Map map, @Nullable String prefix) { if (map == null || map.isEmpty()) { return Collections.emptyMap(); } @@ -508,7 +515,7 @@ static Map filterByPrefix(Map map, String prefix .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue)); } - static Map parseResourceMap(String resourceString) { + static Map parseResourceMap(@Nullable String resourceString) { if (resourceString == null || resourceString.trim().isEmpty()) { return Collections.emptyMap(); } @@ -522,7 +529,7 @@ static Map parseResourceMap(String resourceString) { return resources; } - static Map parseKeyValueMap(String mapString) { + static Map parseKeyValueMap(@Nullable String mapString) { if (mapString == null || mapString.trim().isEmpty()) { return Collections.emptyMap(); } diff --git a/java/src/org/openqa/selenium/grid/node/kubernetes/KubernetesSession.java b/java/src/org/openqa/selenium/grid/node/kubernetes/KubernetesSession.java index 8337889882940..b466892577412 100644 --- a/java/src/org/openqa/selenium/grid/node/kubernetes/KubernetesSession.java +++ b/java/src/org/openqa/selenium/grid/node/kubernetes/KubernetesSession.java @@ -32,6 +32,7 @@ import java.time.Instant; import java.util.logging.Level; import java.util.logging.Logger; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.Capabilities; import org.openqa.selenium.grid.node.DefaultActiveSession; import org.openqa.selenium.internal.Require; @@ -51,20 +52,20 @@ public class KubernetesSession extends DefaultActiveSession { private final String namespace; private final KubernetesClient kubeClient; private final String podName; - private final String assetsPath; - private final String videoFileName; + private final @Nullable String assetsPath; + private final @Nullable String videoFileName; private final long terminationGracePeriodSeconds; - private final LocalPortForward portForward; + private final @Nullable LocalPortForward portForward; KubernetesSession( String jobName, String namespace, KubernetesClient kubeClient, String podName, - String assetsPath, - String videoFileName, + @Nullable String assetsPath, + @Nullable String videoFileName, long terminationGracePeriodSeconds, - LocalPortForward portForward, + @Nullable LocalPortForward portForward, Tracer tracer, HttpClient client, SessionId id, diff --git a/java/src/org/openqa/selenium/grid/node/kubernetes/KubernetesSessionFactory.java b/java/src/org/openqa/selenium/grid/node/kubernetes/KubernetesSessionFactory.java index 6523bac2e1ec2..b918eff88bb9c 100644 --- a/java/src/org/openqa/selenium/grid/node/kubernetes/KubernetesSessionFactory.java +++ b/java/src/org/openqa/selenium/grid/node/kubernetes/KubernetesSessionFactory.java @@ -19,7 +19,6 @@ import static java.util.Optional.ofNullable; import static org.openqa.selenium.remote.Dialect.W3C; -import static org.openqa.selenium.remote.http.Contents.string; import static org.openqa.selenium.remote.http.HttpMethod.GET; import static org.openqa.selenium.remote.tracing.Tags.EXCEPTION; @@ -81,6 +80,7 @@ import java.util.logging.Logger; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.Capabilities; import org.openqa.selenium.Dimension; import org.openqa.selenium.ImmutableCapabilities; @@ -134,19 +134,19 @@ public class KubernetesSessionFactory implements SessionFactory { private final String namespace; private final String browserImage; private final Capabilities stereotype; - private final String imagePullPolicy; - private final String serviceAccount; + private final @Nullable String imagePullPolicy; + private final @Nullable String serviceAccount; private final Map resourceRequests; private final Map resourceLimits; private final Map nodeSelector; - private final String videoImage; - private final String assetsPath; + private final @Nullable String videoImage; + private final @Nullable String assetsPath; private final InheritedPodSpec inheritedPodSpec; - private final Job jobTemplate; + private final @Nullable Job jobTemplate; private final long terminationGracePeriodSeconds; private final boolean usePortForwarding; private final Predicate predicate; - private final OwnerReference nodePodOwnerReference; + private final @Nullable OwnerReference nodePodOwnerReference; public KubernetesSessionFactory( Tracer tracer, @@ -158,12 +158,12 @@ public KubernetesSessionFactory( String browserImage, Capabilities stereotype, String imagePullPolicy, - String serviceAccount, + @Nullable String serviceAccount, Map resourceRequests, Map resourceLimits, Map nodeSelector, - String videoImage, - String assetsPath, + @Nullable String videoImage, + @Nullable String assetsPath, InheritedPodSpec inheritedPodSpec, long terminationGracePeriodSeconds, boolean usePortForwarding, @@ -202,8 +202,8 @@ public KubernetesSessionFactory( String browserImage, Capabilities stereotype, Job jobTemplate, - String videoImage, - String assetsPath, + @Nullable String videoImage, + @Nullable String assetsPath, long terminationGracePeriodSeconds, boolean usePortForwarding, Predicate predicate) { @@ -235,8 +235,8 @@ public KubernetesSessionFactory( String browserImage, Capabilities stereotype, Job jobTemplate, - String videoImage, - String assetsPath, + @Nullable String videoImage, + @Nullable String assetsPath, InheritedPodSpec inheritedPodSpec, long terminationGracePeriodSeconds, boolean usePortForwarding, @@ -319,7 +319,7 @@ public Either apply(CreateSessionRequest sess LOG.info("Starting K8s session for " + sessionRequest.getDesiredCapabilities()); String browserName = sessionRequest.getDesiredCapabilities().getBrowserName(); - if (browserName == null || browserName.isEmpty()) { + if (browserName.isEmpty()) { browserName = "unknown"; } else { browserName = browserName.toLowerCase(); @@ -539,7 +539,9 @@ private String generateJobName(String browserName, long timestamp, String unique return name; } - private static OwnerReference createNodePodOwnerReference(InheritedPodSpec inheritedPodSpec) { + @Nullable + private static OwnerReference createNodePodOwnerReference( + @Nullable InheritedPodSpec inheritedPodSpec) { if (inheritedPodSpec == null || !inheritedPodSpec.hasNodePodOwnerReference()) { return null; } @@ -571,7 +573,7 @@ Job buildJobSpec(String jobName, Capabilities sessionCapabilities) { labels.put("app", "selenium-session"); labels.put("se/job-name", jobName); String browser = sessionCapabilities.getBrowserName(); - if (browser != null && !browser.isEmpty()) { + if (!browser.isEmpty()) { labels.put("se/browser", browser.toLowerCase()); } @@ -861,6 +863,7 @@ private Container buildVideoContainer(String jobName, Capabilities sessionCapabi .build(); } + @Nullable private String getVideoFileName(Capabilities sessionRequestCapabilities, String capabilityName) { String trimRegex = getVideoFileNameTrimRegex(); Optional testName = @@ -916,7 +919,7 @@ Job buildJobSpecFromTemplate(String jobName, Capabilities sessionCapabilities) { labels.put("app", "selenium-session"); labels.put("se/job-name", jobName); String browser = sessionCapabilities.getBrowserName(); - if (browser != null && !browser.isEmpty()) { + if (!browser.isEmpty()) { labels.put("se/browser", browser.toLowerCase()); } @@ -990,7 +993,8 @@ && recordVideoForSession(sessionCapabilities)) { return job; } - static Container findContainerByName(List containers, String name) { + @Nullable + static Container findContainerByName(@Nullable List containers, String name) { if (containers == null) { return null; } @@ -1059,7 +1063,8 @@ static void ensurePort(Container container, int port) { } } - static void ensureVolumeMount(Container container, String volumeName, String mountPath) { + static void ensureVolumeMount( + @Nullable Container container, String volumeName, String mountPath) { if (container == null) { return; } @@ -1147,7 +1152,7 @@ private String[] doWaitForPodRunning(String jobName) { .inNamespace(namespace) .withLabel("job-name", jobName) .watch( - new Watcher() { + new Watcher<>() { @Override public void eventReceived(Action action, Pod pod) { if (action == Action.DELETED) { @@ -1166,7 +1171,7 @@ public void eventReceived(Action action, Pod pod) { } @Override - public void onClose(WatcherException cause) { + public void onClose(@Nullable WatcherException cause) { if (!future.isDone() && cause != null) { future.completeExceptionally( new SessionNotCreatedException( @@ -1283,11 +1288,12 @@ private boolean isPodReady(Pod pod) { return true; } + @Nullable private String resolvePodIp(Pod pod) { if (pod.getStatus() == null) { return null; } - List podIps = pod.getStatus().getPodIPs(); + List<@Nullable PodIP> podIps = pod.getStatus().getPodIPs(); if (podIps != null) { for (PodIP podIp : podIps) { if (podIp != null && podIp.getIp() != null && !podIp.getIp().isBlank()) { @@ -1309,7 +1315,7 @@ private void waitForServerToStart(HttpClient client, Duration duration) { wait.until( obj -> { HttpResponse response = client.execute(new HttpRequest(GET, "/status")); - LOG.fine(string(response)); + LOG.fine(response::contentAsString); if (401 == response.getStatus()) { LOG.warning( "Server requires basic authentication. " @@ -1339,7 +1345,7 @@ private Capabilities addForwardCdpEndpoint( .setCapability("se:forwardCdp", forwardCdpPath); } - private void closePortForward(LocalPortForward portForward) { + private void closePortForward(@Nullable LocalPortForward portForward) { if (portForward != null) { try { portForward.close(); @@ -1387,6 +1393,7 @@ private URL getUrl(String host, int port) { } } + @Nullable private TimeZone getTimeZone(Capabilities sessionRequestCapabilities) { Optional timeZone = ofNullable(sessionRequestCapabilities.getCapability("se:timeZone")); if (timeZone.isPresent()) { @@ -1408,6 +1415,7 @@ private boolean recordVideoForSession(Capabilities sessionRequestCapabilities) { return recordVideo.isPresent() && Boolean.parseBoolean(recordVideo.get().toString()); } + @Nullable private Dimension getScreenResolution(Capabilities sessionRequestCapabilities) { Optional screenResolution = ofNullable(sessionRequestCapabilities.getCapability("se:screenResolution")); diff --git a/java/src/org/openqa/selenium/grid/node/kubernetes/package-info.java b/java/src/org/openqa/selenium/grid/node/kubernetes/package-info.java new file mode 100644 index 0000000000000..6f37afbf08e4c --- /dev/null +++ b/java/src/org/openqa/selenium/grid/node/kubernetes/package-info.java @@ -0,0 +1,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.grid.node.kubernetes; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/node/local/BUILD.bazel b/java/src/org/openqa/selenium/grid/node/local/BUILD.bazel index 3a29f82adb381..d33fea9fc67d9 100644 --- a/java/src/org/openqa/selenium/grid/node/local/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/node/local/BUILD.bazel @@ -29,5 +29,6 @@ java_library( "//java/src/org/openqa/selenium/remote", artifact("com.google.guava:guava"), artifact("com.github.ben-manes.caffeine:caffeine"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/node/local/LocalNode.java b/java/src/org/openqa/selenium/grid/node/local/LocalNode.java index b1d9fde09ad53..c2aaeaa1a0bb9 100644 --- a/java/src/org/openqa/selenium/grid/node/local/LocalNode.java +++ b/java/src/org/openqa/selenium/grid/node/local/LocalNode.java @@ -76,6 +76,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.Capabilities; import org.openqa.selenium.ImmutableCapabilities; import org.openqa.selenium.MutableCapabilities; @@ -171,7 +172,7 @@ protected LocalNode( EventBus bus, URI uri, URI gridUri, - HealthCheck healthCheck, + @Nullable HealthCheck healthCheck, int maxSessionCount, int drainAfterSessionCount, boolean cdpEnabled, @@ -337,7 +338,8 @@ public void close() { shutdown.run(); } - private void stopTimedOutSession(SessionId id, SessionSlot slot, RemovalCause cause) { + private void stopTimedOutSession( + @Nullable SessionId id, @Nullable SessionSlot slot, RemovalCause cause) { try (Span span = tracer.getCurrentContext().createSpan("node.stop_session")) { AttributeMap attributeMap = tracer.createAttributeMap(); attributeMap.put(AttributeKey.LOGGER_CLASS.getKey(), getClass().getName()); @@ -1013,7 +1015,7 @@ private HttpResponse deleteDownloadedFile(File downloadsDirectory) { for (File file : files) { FileHandler.delete(file); } - Map toReturn = new HashMap<>(); + Map toReturn = new HashMap<>(); toReturn.put("value", null); return new HttpResponse().setContent(asJson(toReturn)); } diff --git a/java/src/org/openqa/selenium/grid/node/local/SessionSlot.java b/java/src/org/openqa/selenium/grid/node/local/SessionSlot.java index fee8b5789101e..cc615d46dcb38 100644 --- a/java/src/org/openqa/selenium/grid/node/local/SessionSlot.java +++ b/java/src/org/openqa/selenium/grid/node/local/SessionSlot.java @@ -29,6 +29,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.StreamSupport; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.Capabilities; import org.openqa.selenium.ImmutableCapabilities; import org.openqa.selenium.NoSuchSessionException; @@ -67,7 +68,7 @@ public class SessionSlot private final boolean supportingBiDi; private final AtomicLong connectionCounter; // volatile ensures memory visibility across threads when session is set after reservation - private volatile ActiveSession currentSession; + private volatile @Nullable ActiveSession currentSession; public SessionSlot(EventBus bus, Capabilities stereotype, SessionFactory factory) { this.bus = Require.nonNull("Event bus", bus); @@ -118,6 +119,7 @@ public boolean isAvailable() { return !reserved.get(); } + @Nullable public ActiveSession getSession() { if (isAvailable()) { throw new NoSuchSessionException("Session is not running"); @@ -143,7 +145,7 @@ public void stop(SessionClosedReason reason) { * @param nodeUri the URI of the node where the session was running (may be null for backward * compatibility) */ - public void stop(SessionClosedReason reason, NodeId nodeId, URI nodeUri) { + public void stop(SessionClosedReason reason, @Nullable NodeId nodeId, @Nullable URI nodeUri) { if (isAvailable()) { return; } diff --git a/java/src/org/openqa/selenium/grid/node/local/package-info.java b/java/src/org/openqa/selenium/grid/node/local/package-info.java new file mode 100644 index 0000000000000..f47f0602b0030 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/node/local/package-info.java @@ -0,0 +1,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.grid.node.local; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/node/package-info.java b/java/src/org/openqa/selenium/grid/node/package-info.java new file mode 100644 index 0000000000000..f858c033d8a46 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/node/package-info.java @@ -0,0 +1,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.grid.node; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/node/relay/BUILD.bazel b/java/src/org/openqa/selenium/grid/node/relay/BUILD.bazel index a9e354cd1ef94..0ed95a851837a 100644 --- a/java/src/org/openqa/selenium/grid/node/relay/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/node/relay/BUILD.bazel @@ -17,5 +17,6 @@ java_library( "//java/src/org/openqa/selenium/remote", artifact("com.beust:jcommander"), artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/node/relay/RelayOptions.java b/java/src/org/openqa/selenium/grid/node/relay/RelayOptions.java index 3342a585c2b7e..ac7902438c966 100644 --- a/java/src/org/openqa/selenium/grid/node/relay/RelayOptions.java +++ b/java/src/org/openqa/selenium/grid/node/relay/RelayOptions.java @@ -17,7 +17,6 @@ package org.openqa.selenium.grid.node.relay; -import static org.openqa.selenium.remote.http.Contents.string; import static org.openqa.selenium.remote.http.HttpMethod.GET; import java.net.URI; @@ -30,6 +29,7 @@ import java.util.Map; import java.util.Optional; import java.util.logging.Logger; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.Capabilities; import org.openqa.selenium.ImmutableCapabilities; import org.openqa.selenium.grid.config.Config; @@ -87,6 +87,7 @@ public URI getServiceUri() { } } + @Nullable public URI getServiceStatusUri() { try { if (config.get(RELAY_SECTION, "status-endpoint").isEmpty()) { @@ -134,7 +135,7 @@ private boolean isServiceUp(HttpClient client) { } try { HttpResponse response = client.execute(new HttpRequest(GET, serviceStatusUri.toString())); - LOG.fine(string(response)); + LOG.fine(response::contentAsString); return 200 == response.getStatus(); } catch (Exception e) { throw new ConfigException("Unable to reach the service at " + getServiceUri(), e); diff --git a/java/src/org/openqa/selenium/grid/node/relay/RelaySessionFactory.java b/java/src/org/openqa/selenium/grid/node/relay/RelaySessionFactory.java index 493b368956802..8dd43d5a90e39 100644 --- a/java/src/org/openqa/selenium/grid/node/relay/RelaySessionFactory.java +++ b/java/src/org/openqa/selenium/grid/node/relay/RelaySessionFactory.java @@ -39,6 +39,7 @@ import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.Capabilities; import org.openqa.selenium.ImmutableCapabilities; import org.openqa.selenium.MutableCapabilities; @@ -59,7 +60,6 @@ import org.openqa.selenium.remote.Response; import org.openqa.selenium.remote.SessionId; import org.openqa.selenium.remote.http.ClientConfig; -import org.openqa.selenium.remote.http.Contents; import org.openqa.selenium.remote.http.HttpClient; import org.openqa.selenium.remote.http.HttpMethod; import org.openqa.selenium.remote.http.HttpRequest; @@ -77,7 +77,7 @@ public class RelaySessionFactory implements SessionFactory { private final HttpClient.Factory clientFactory; private final Duration sessionTimeout; private final URL serviceUrl; - private final URL serviceStatusUrl; + private final @Nullable URL serviceStatusUrl; private final String serviceProtocolVersion; private final Capabilities stereotype; @@ -86,13 +86,13 @@ public RelaySessionFactory( HttpClient.Factory clientFactory, Duration sessionTimeout, URI serviceUri, - URI serviceStatusUri, + @Nullable URI serviceStatusUri, String serviceProtocolVersion, Capabilities stereotype) { this.tracer = Require.nonNull("Tracer", tracer); this.clientFactory = Require.nonNull("HTTP client", clientFactory); this.sessionTimeout = Require.nonNull("Session timeout", sessionTimeout); - this.serviceUrl = createUrlFromUri(Require.nonNull("Service URL", serviceUri)); + this.serviceUrl = Require.nonNull("Service URL", createUrlFromUri(serviceUri)); this.serviceStatusUrl = createUrlFromUri(serviceStatusUri); this.serviceProtocolVersion = Require.nonNull("Service protocol version", serviceProtocolVersion); @@ -244,7 +244,7 @@ public boolean isServiceUp() { try (HttpClient client = clientFactory.createClient(clientConfig)) { HttpResponse response = client.execute(new HttpRequest(HttpMethod.GET, serviceStatusUrl.toString())); - LOG.log(Debug.getDebugLogLevel(), () -> Contents.string(response)); + LOG.log(Debug.getDebugLogLevel(), response::contentAsString); return response.getStatus() == 200; } catch (Exception e) { LOG.log( @@ -257,7 +257,8 @@ public boolean isServiceUp() { return false; } - private URL createUrlFromUri(URI uri) { + @Nullable + private URL createUrlFromUri(@Nullable URI uri) { if (uri == null) { return null; } diff --git a/java/src/org/openqa/selenium/grid/node/relay/package-info.java b/java/src/org/openqa/selenium/grid/node/relay/package-info.java new file mode 100644 index 0000000000000..d0133b3427817 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/node/relay/package-info.java @@ -0,0 +1,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.grid.node.relay; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/node/remote/BUILD.bazel b/java/src/org/openqa/selenium/grid/node/remote/BUILD.bazel index 400855ed6a686..c2801d30992c5 100644 --- a/java/src/org/openqa/selenium/grid/node/remote/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/node/remote/BUILD.bazel @@ -18,5 +18,6 @@ java_library( "//java/src/org/openqa/selenium/json", "//java/src/org/openqa/selenium/remote", artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/node/remote/RemoteNode.java b/java/src/org/openqa/selenium/grid/node/remote/RemoteNode.java index 0d0832e658b22..de8f1235c4ccd 100644 --- a/java/src/org/openqa/selenium/grid/node/remote/RemoteNode.java +++ b/java/src/org/openqa/selenium/grid/node/remote/RemoteNode.java @@ -243,7 +243,7 @@ public Session getSession(SessionId id) throws NoSuchSessionException { HttpResponse res = client.with(addSecret).execute(req); - return Values.get(res, Session.class); + return Require.nonNull("Session", Values.get(res, Session.class)); } @Override @@ -299,7 +299,7 @@ private NodeStatus getStatus(HttpHandler handler) { while (in.hasNext()) { if ("node".equals(in.nextName())) { - return in.read(NodeStatus.class); + return in.readNonNull(NodeStatus.class); } else { in.skipValue(); } diff --git a/java/src/org/openqa/selenium/grid/node/remote/package-info.java b/java/src/org/openqa/selenium/grid/node/remote/package-info.java new file mode 100644 index 0000000000000..f026ca4da35cb --- /dev/null +++ b/java/src/org/openqa/selenium/grid/node/remote/package-info.java @@ -0,0 +1,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.grid.node.remote; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/package-info.java b/java/src/org/openqa/selenium/grid/package-info.java index 38cfdad52888b..35fc148c138f2 100644 --- a/java/src/org/openqa/selenium/grid/package-info.java +++ b/java/src/org/openqa/selenium/grid/package-info.java @@ -15,8 +15,6 @@ // specific language governing permissions and limitations // under the License. -package org.openqa.selenium.grid; - /** * The Selenium Grid is composed of a number of moving pieces, all of which are designed to be used * either locally or across an HTTP boundary. @@ -37,3 +35,7 @@ * which the {@code Node} is running. Conversely, when the session comes to an end, the {@code Node} * is responsible for ensuring that the session is removed from the {@code SessionMap}. */ +@NullMarked +package org.openqa.selenium.grid; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/router/BUILD.bazel b/java/src/org/openqa/selenium/grid/router/BUILD.bazel index 70065bd707e4e..02368b044c94c 100644 --- a/java/src/org/openqa/selenium/grid/router/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/router/BUILD.bazel @@ -24,5 +24,6 @@ java_library( "//java/src/org/openqa/selenium/remote", "//java/src/org/openqa/selenium/status", artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/router/httpd/BUILD.bazel b/java/src/org/openqa/selenium/grid/router/httpd/BUILD.bazel index 782f0b52af005..9f44ba247ca57 100644 --- a/java/src/org/openqa/selenium/grid/router/httpd/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/router/httpd/BUILD.bazel @@ -33,5 +33,6 @@ java_library( "//java/src/org/openqa/selenium/remote", artifact("com.beust:jcommander"), artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/router/httpd/package-info.java b/java/src/org/openqa/selenium/grid/router/httpd/package-info.java new file mode 100644 index 0000000000000..fdd71e1265265 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/router/httpd/package-info.java @@ -0,0 +1,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.grid.router.httpd; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/router/package-info.java b/java/src/org/openqa/selenium/grid/router/package-info.java new file mode 100644 index 0000000000000..1ed3dadc439f8 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/router/package-info.java @@ -0,0 +1,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.grid.router; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/security/BUILD.bazel b/java/src/org/openqa/selenium/grid/security/BUILD.bazel index ae959d8c1d8c4..0fc8246210bed 100644 --- a/java/src/org/openqa/selenium/grid/security/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/security/BUILD.bazel @@ -17,5 +17,6 @@ java_library( "//java/src/org/openqa/selenium/json", "//java/src/org/openqa/selenium/remote/http", artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/security/BasicAuthenticationFilter.java b/java/src/org/openqa/selenium/grid/security/BasicAuthenticationFilter.java index 90a8c5e858e0b..9dadae5a623fd 100644 --- a/java/src/org/openqa/selenium/grid/security/BasicAuthenticationFilter.java +++ b/java/src/org/openqa/selenium/grid/security/BasicAuthenticationFilter.java @@ -22,6 +22,7 @@ import java.net.HttpURLConnection; import java.util.Base64; import java.util.logging.Logger; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.internal.Require; import org.openqa.selenium.remote.http.Filter; import org.openqa.selenium.remote.http.HttpHandler; @@ -55,7 +56,7 @@ public HttpHandler apply(HttpHandler next) { }; } - private boolean isAuthorized(String auth) { + private boolean isAuthorized(@Nullable String auth) { if (auth != null) { final int index = auth.indexOf(' ') + 1; diff --git a/java/src/org/openqa/selenium/grid/security/SecretOptions.java b/java/src/org/openqa/selenium/grid/security/SecretOptions.java index bc8bb36c92ce0..250ab0e08391d 100644 --- a/java/src/org/openqa/selenium/grid/security/SecretOptions.java +++ b/java/src/org/openqa/selenium/grid/security/SecretOptions.java @@ -24,6 +24,7 @@ import java.nio.file.Files; import java.util.Arrays; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.UsernameAndPassword; import org.openqa.selenium.grid.config.Config; import org.openqa.selenium.grid.config.ConfigException; @@ -58,6 +59,7 @@ public Secret getRegistrationSecret() { .orElse(new Secret(secret)); } + @Nullable public UsernameAndPassword getServerAuthentication() { Optional username = config.get(ROUTER_SECTION, "username"); Optional password = config.get(ROUTER_SECTION, "password"); diff --git a/java/src/org/openqa/selenium/grid/security/package-info.java b/java/src/org/openqa/selenium/grid/security/package-info.java new file mode 100644 index 0000000000000..29b62cab27d5a --- /dev/null +++ b/java/src/org/openqa/selenium/grid/security/package-info.java @@ -0,0 +1,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.grid.security; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/server/BUILD.bazel b/java/src/org/openqa/selenium/grid/server/BUILD.bazel index bb5d132803c3c..cdcadab917182 100644 --- a/java/src/org/openqa/selenium/grid/server/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/server/BUILD.bazel @@ -23,5 +23,6 @@ java_library( "//java/src/org/openqa/selenium/remote", artifact("com.beust:jcommander"), artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/server/BaseServerOptions.java b/java/src/org/openqa/selenium/grid/server/BaseServerOptions.java index 73347a593c5d0..c0ab6164e29f1 100644 --- a/java/src/org/openqa/selenium/grid/server/BaseServerOptions.java +++ b/java/src/org/openqa/selenium/grid/server/BaseServerOptions.java @@ -22,6 +22,7 @@ import java.net.URISyntaxException; import java.util.Optional; import java.util.logging.Logger; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.WebDriverException; import org.openqa.selenium.grid.config.Config; import org.openqa.selenium.grid.config.ConfigException; @@ -48,7 +49,7 @@ public BaseServerOptions(Config config) { new JMXHelper().register(this); } - public Optional getHostname() { + public Optional<@Nullable String> getHostname() { return config.get(SERVER_SECTION, "host"); } diff --git a/java/src/org/openqa/selenium/grid/server/EventBusOptions.java b/java/src/org/openqa/selenium/grid/server/EventBusOptions.java index a78e833186465..dd3d5dd86ec75 100644 --- a/java/src/org/openqa/selenium/grid/server/EventBusOptions.java +++ b/java/src/org/openqa/selenium/grid/server/EventBusOptions.java @@ -18,6 +18,7 @@ package org.openqa.selenium.grid.server; import java.time.Duration; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.events.EventBus; import org.openqa.selenium.grid.config.Config; import org.openqa.selenium.internal.Require; @@ -28,7 +29,7 @@ public class EventBusOptions { private static final String DEFAULT_CLASS = "org.openqa.selenium.events.zeromq.ZeroMqEventBus"; private static final int DEFAULT_HEARTBEAT_PERIOD = 60; private final Config config; - private volatile EventBus bus; + private volatile @Nullable EventBus bus; public EventBusOptions(Config config) { this.config = Require.nonNull("Config", config); diff --git a/java/src/org/openqa/selenium/grid/server/package-info.java b/java/src/org/openqa/selenium/grid/server/package-info.java new file mode 100644 index 0000000000000..adecd3fa97fd3 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/server/package-info.java @@ -0,0 +1,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.grid.server; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/session/BUILD.bazel b/java/src/org/openqa/selenium/grid/session/BUILD.bazel index 4195249e38602..77100fb69baa5 100644 --- a/java/src/org/openqa/selenium/grid/session/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/session/BUILD.bazel @@ -16,5 +16,6 @@ java_library( "//java/src/org/openqa/selenium/grid/web", "//java/src/org/openqa/selenium/remote", artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/session/package-info.java b/java/src/org/openqa/selenium/grid/session/package-info.java new file mode 100644 index 0000000000000..c5aca77dd7376 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/session/package-info.java @@ -0,0 +1,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.grid.session; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/sessionmap/BUILD.bazel b/java/src/org/openqa/selenium/grid/sessionmap/BUILD.bazel index 0c8d812e8c185..8b0b62764775e 100644 --- a/java/src/org/openqa/selenium/grid/sessionmap/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/sessionmap/BUILD.bazel @@ -19,5 +19,6 @@ java_library( "//java/src/org/openqa/selenium/remote/http", "//java/src/org/openqa/selenium/status", artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/sessionmap/config/BUILD.bazel b/java/src/org/openqa/selenium/grid/sessionmap/config/BUILD.bazel index b91fb3f78062e..052be637fdab7 100644 --- a/java/src/org/openqa/selenium/grid/sessionmap/config/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/sessionmap/config/BUILD.bazel @@ -13,5 +13,6 @@ java_library( "//java/src/org/openqa/selenium/grid/server", "//java/src/org/openqa/selenium/grid/sessionmap", artifact("com.beust:jcommander"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/sessionmap/config/package-info.java b/java/src/org/openqa/selenium/grid/sessionmap/config/package-info.java new file mode 100644 index 0000000000000..cc2417130c9da --- /dev/null +++ b/java/src/org/openqa/selenium/grid/sessionmap/config/package-info.java @@ -0,0 +1,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.grid.sessionmap.config; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/sessionmap/httpd/BUILD.bazel b/java/src/org/openqa/selenium/grid/sessionmap/httpd/BUILD.bazel index 61bbd869ee58d..a7df6e94aca57 100644 --- a/java/src/org/openqa/selenium/grid/sessionmap/httpd/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/sessionmap/httpd/BUILD.bazel @@ -21,5 +21,6 @@ java_library( "//java/src/org/openqa/selenium/netty/server", artifact("com.beust:jcommander"), artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/sessionmap/httpd/package-info.java b/java/src/org/openqa/selenium/grid/sessionmap/httpd/package-info.java new file mode 100644 index 0000000000000..36fff457cdb04 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/sessionmap/httpd/package-info.java @@ -0,0 +1,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.grid.sessionmap.httpd; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/sessionmap/jdbc/JdbcBackedSessionMap.java b/java/src/org/openqa/selenium/grid/sessionmap/jdbc/JdbcBackedSessionMap.java index 9746000c27f1c..aba579061bac7 100644 --- a/java/src/org/openqa/selenium/grid/sessionmap/jdbc/JdbcBackedSessionMap.java +++ b/java/src/org/openqa/selenium/grid/sessionmap/jdbc/JdbcBackedSessionMap.java @@ -32,6 +32,7 @@ import java.sql.SQLException; import java.time.Instant; import java.util.logging.Logger; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.Capabilities; import org.openqa.selenium.ImmutableCapabilities; import org.openqa.selenium.NoSuchSessionException; @@ -69,22 +70,21 @@ public class JdbcBackedSessionMap extends SessionMap implements Closeable { private static final String DATABASE_USER = AttributeKey.DATABASE_USER.getKey(); private static final String DATABASE_CONNECTION_STRING = AttributeKey.DATABASE_CONNECTION_STRING.getKey(); - private static String jdbcUser; - private static String jdbcUrl; - private final EventBus bus; + private static @Nullable String jdbcUser; + private static @Nullable String jdbcUrl; private final Connection connection; public JdbcBackedSessionMap(Tracer tracer, Connection jdbcConnection, EventBus bus) { super(tracer); Require.nonNull("JDBC Connection Object", jdbcConnection); - this.bus = Require.nonNull("Event bus", bus); + Require.nonNull("Event bus", bus); this.connection = jdbcConnection; // Listen to SessionClosedEvent and extract the sessionId - this.bus.addListener(SessionClosedEvent.sessionListener(this::remove)); + bus.addListener(SessionClosedEvent.sessionListener(this::remove)); - this.bus.addListener( + bus.addListener( NodeRemovedEvent.listener( nodeStatus -> nodeStatus.getSlots().stream() @@ -272,6 +272,7 @@ public Session get(SessionId id) throws NoSuchSessionException { } span.addEvent("Retrieved session from the database", attributeMap); + //noinspection DataFlowIssue return new Session(id, uri, stereotype, caps, start); } catch (SQLException e) { span.setAttribute("error", true); diff --git a/java/src/org/openqa/selenium/grid/sessionmap/jdbc/package-info.java b/java/src/org/openqa/selenium/grid/sessionmap/jdbc/package-info.java new file mode 100644 index 0000000000000..f8b28572af4e4 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/sessionmap/jdbc/package-info.java @@ -0,0 +1,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.grid.sessionmap.jdbc; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/sessionmap/local/BUILD.bazel b/java/src/org/openqa/selenium/grid/sessionmap/local/BUILD.bazel index 94b7c1589708c..414ec99776a03 100644 --- a/java/src/org/openqa/selenium/grid/sessionmap/local/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/sessionmap/local/BUILD.bazel @@ -18,5 +18,6 @@ java_library( "//java/src/org/openqa/selenium/grid/sessionmap", "//java/src/org/openqa/selenium/remote", artifact("com.github.ben-manes.caffeine:caffeine"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/sessionmap/local/LocalSessionMap.java b/java/src/org/openqa/selenium/grid/sessionmap/local/LocalSessionMap.java index 159c6336c4d75..b47d286c4f782 100644 --- a/java/src/org/openqa/selenium/grid/sessionmap/local/LocalSessionMap.java +++ b/java/src/org/openqa/selenium/grid/sessionmap/local/LocalSessionMap.java @@ -33,6 +33,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.logging.Logger; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.NoSuchSessionException; import org.openqa.selenium.events.EventBus; import org.openqa.selenium.grid.config.Config; @@ -213,6 +214,7 @@ private static class IndexedSessionMap { private final ConcurrentMap> sessionsByUri = new ConcurrentHashMap<>(); private final Object coordinationLock = new Object(); + @Nullable public Session get(SessionId id) { return sessions.get(id); } @@ -232,6 +234,7 @@ public void put(SessionId id, Session session) { } } + @Nullable public Session remove(SessionId id) { synchronized (coordinationLock) { Session removed = sessions.remove(id); diff --git a/java/src/org/openqa/selenium/grid/sessionmap/local/package-info.java b/java/src/org/openqa/selenium/grid/sessionmap/local/package-info.java new file mode 100644 index 0000000000000..b1e9ea1bc027f --- /dev/null +++ b/java/src/org/openqa/selenium/grid/sessionmap/local/package-info.java @@ -0,0 +1,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.grid.sessionmap.local; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/sessionmap/package-info.java b/java/src/org/openqa/selenium/grid/sessionmap/package-info.java new file mode 100644 index 0000000000000..025b77cc59fb7 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/sessionmap/package-info.java @@ -0,0 +1,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.grid.sessionmap; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/sessionmap/redis/BUILD.bazel b/java/src/org/openqa/selenium/grid/sessionmap/redis/BUILD.bazel index d29484ba06b29..5b9275d4eb11c 100644 --- a/java/src/org/openqa/selenium/grid/sessionmap/redis/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/sessionmap/redis/BUILD.bazel @@ -24,5 +24,6 @@ java_export( "//java/src/org/openqa/selenium/remote", artifact("com.google.guava:guava"), artifact("io.lettuce:lettuce-core"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/sessionmap/redis/RedisBackedSessionMap.java b/java/src/org/openqa/selenium/grid/sessionmap/redis/RedisBackedSessionMap.java index f21f5fabb1d48..e989b91c4df30 100644 --- a/java/src/org/openqa/selenium/grid/sessionmap/redis/RedisBackedSessionMap.java +++ b/java/src/org/openqa/selenium/grid/sessionmap/redis/RedisBackedSessionMap.java @@ -64,19 +64,18 @@ public class RedisBackedSessionMap extends SessionMap { private static final String DATABASE_SYSTEM = AttributeKey.DATABASE_SYSTEM.getKey(); private static final String DATABASE_OPERATION = AttributeKey.DATABASE_OPERATION.getKey(); private final GridRedisClient connection; - private final EventBus bus; private final URI serverUri; public RedisBackedSessionMap(Tracer tracer, URI serverUri, EventBus bus) { super(tracer); Require.nonNull("Redis Server Uri", serverUri); - this.bus = Require.nonNull("Event bus", bus); + Require.nonNull("Event bus", bus); this.connection = new GridRedisClient(serverUri); this.serverUri = serverUri; - this.bus.addListener(SessionClosedEvent.sessionListener(this::remove)); + bus.addListener(SessionClosedEvent.sessionListener(this::remove)); - this.bus.addListener( + bus.addListener( NodeRemovedEvent.listener( nodeStatus -> nodeStatus.getSlots().stream() @@ -195,6 +194,7 @@ public Session get(SessionId id) throws NoSuchSessionException { CAPABILITIES_EVENT.accept(attributeMap, caps); span.addEvent("Retrieved session from the database", attributeMap); + //noinspection DataFlowIssue return new Session(id, uri, stereotype, caps, start); } } diff --git a/java/src/org/openqa/selenium/grid/sessionmap/redis/package-info.java b/java/src/org/openqa/selenium/grid/sessionmap/redis/package-info.java new file mode 100644 index 0000000000000..2fdbf65aadb04 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/sessionmap/redis/package-info.java @@ -0,0 +1,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.grid.sessionmap.redis; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/sessionmap/remote/BUILD.bazel b/java/src/org/openqa/selenium/grid/sessionmap/remote/BUILD.bazel index 1d250a65cbb16..59a80b1d3999a 100644 --- a/java/src/org/openqa/selenium/grid/sessionmap/remote/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/sessionmap/remote/BUILD.bazel @@ -1,3 +1,4 @@ +load("@rules_jvm_external//:defs.bzl", "artifact") load("//java:defs.bzl", "java_library") java_library( @@ -16,5 +17,6 @@ java_library( "//java/src/org/openqa/selenium/grid/sessionmap/config", "//java/src/org/openqa/selenium/grid/web", "//java/src/org/openqa/selenium/remote", + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/sessionmap/remote/RemoteSessionMap.java b/java/src/org/openqa/selenium/grid/sessionmap/remote/RemoteSessionMap.java index 5d49e2b6588c8..10383bb96c349 100644 --- a/java/src/org/openqa/selenium/grid/sessionmap/remote/RemoteSessionMap.java +++ b/java/src/org/openqa/selenium/grid/sessionmap/remote/RemoteSessionMap.java @@ -17,6 +17,7 @@ package org.openqa.selenium.grid.sessionmap.remote; +import static java.util.Objects.requireNonNull; import static org.openqa.selenium.remote.http.Contents.asJson; import static org.openqa.selenium.remote.http.HttpMethod.DELETE; import static org.openqa.selenium.remote.http.HttpMethod.GET; @@ -26,6 +27,7 @@ import java.lang.reflect.Type; import java.net.MalformedURLException; import java.net.URI; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.NoSuchSessionException; import org.openqa.selenium.grid.config.Config; import org.openqa.selenium.grid.data.Session; @@ -79,7 +81,7 @@ public boolean add(Session session) { HttpRequest request = new HttpRequest(POST, "/se/grid/session"); request.setContent(asJson(session)); - return makeRequest(request, Boolean.class); + return requireNonNull(makeRequest(request, Boolean.class)); } @Override @@ -111,6 +113,7 @@ public void remove(SessionId id) { makeRequest(new HttpRequest(DELETE, "/se/grid/session/" + id), Void.class); } + @Nullable private T makeRequest(HttpRequest request, Type typeOfT) { HttpTracing.inject(tracer, tracer.getCurrentContext(), request); diff --git a/java/src/org/openqa/selenium/grid/sessionmap/remote/package-info.java b/java/src/org/openqa/selenium/grid/sessionmap/remote/package-info.java new file mode 100644 index 0000000000000..54737da86682b --- /dev/null +++ b/java/src/org/openqa/selenium/grid/sessionmap/remote/package-info.java @@ -0,0 +1,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.grid.sessionmap.remote; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/sessionqueue/BUILD.bazel b/java/src/org/openqa/selenium/grid/sessionqueue/BUILD.bazel index 5f8c1b2f43e8f..c271ee4a19a72 100644 --- a/java/src/org/openqa/selenium/grid/sessionqueue/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/sessionqueue/BUILD.bazel @@ -23,5 +23,6 @@ java_library( "//java/src/org/openqa/selenium/remote/http", "//java/src/org/openqa/selenium/status", artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/sessionqueue/config/BUILD.bazel b/java/src/org/openqa/selenium/grid/sessionqueue/config/BUILD.bazel index 1e1d4f5482a0c..084b96412213d 100644 --- a/java/src/org/openqa/selenium/grid/sessionqueue/config/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/sessionqueue/config/BUILD.bazel @@ -15,5 +15,6 @@ java_library( "//java/src/org/openqa/selenium/grid/server", "//java/src/org/openqa/selenium/grid/sessionqueue", artifact("com.beust:jcommander"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/sessionqueue/config/package-info.java b/java/src/org/openqa/selenium/grid/sessionqueue/config/package-info.java new file mode 100644 index 0000000000000..d73cbede10e00 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/sessionqueue/config/package-info.java @@ -0,0 +1,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.grid.sessionqueue.config; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/sessionqueue/httpd/BUILD.bazel b/java/src/org/openqa/selenium/grid/sessionqueue/httpd/BUILD.bazel index 91cb97059421e..55c443be94687 100644 --- a/java/src/org/openqa/selenium/grid/sessionqueue/httpd/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/sessionqueue/httpd/BUILD.bazel @@ -22,5 +22,6 @@ java_library( "//java/src/org/openqa/selenium/netty/server", artifact("com.beust:jcommander"), artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/sessionqueue/httpd/package-info.java b/java/src/org/openqa/selenium/grid/sessionqueue/httpd/package-info.java new file mode 100644 index 0000000000000..c3bd786e10df0 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/sessionqueue/httpd/package-info.java @@ -0,0 +1,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.grid.sessionqueue.httpd; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/sessionqueue/local/BUILD.bazel b/java/src/org/openqa/selenium/grid/sessionqueue/local/BUILD.bazel index 601027e3142ff..ed8a8e69bbfdc 100644 --- a/java/src/org/openqa/selenium/grid/sessionqueue/local/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/sessionqueue/local/BUILD.bazel @@ -23,5 +23,6 @@ java_library( "//java/src/org/openqa/selenium/grid/sessionqueue/config", "//java/src/org/openqa/selenium/remote", artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/sessionqueue/local/LocalNewSessionQueue.java b/java/src/org/openqa/selenium/grid/sessionqueue/local/LocalNewSessionQueue.java index 8995553652080..75a46cf8db112 100644 --- a/java/src/org/openqa/selenium/grid/sessionqueue/local/LocalNewSessionQueue.java +++ b/java/src/org/openqa/selenium/grid/sessionqueue/local/LocalNewSessionQueue.java @@ -42,6 +42,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.function.Predicate; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.Capabilities; import org.openqa.selenium.SessionNotCreatedException; import org.openqa.selenium.concurrent.GuardedRunnable; @@ -110,7 +111,8 @@ public class LocalNewSessionQueue extends NewSessionQueue implements Closeable { thread.setName(NAME); return thread; }); - private final MBean jmxBean; + + @Nullable private final MBean jmxBean; public LocalNewSessionQueue( Tracer tracer, diff --git a/java/src/org/openqa/selenium/grid/sessionqueue/local/package-info.java b/java/src/org/openqa/selenium/grid/sessionqueue/local/package-info.java new file mode 100644 index 0000000000000..708feadfdf3ad --- /dev/null +++ b/java/src/org/openqa/selenium/grid/sessionqueue/local/package-info.java @@ -0,0 +1,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.grid.sessionqueue.local; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/sessionqueue/package-info.java b/java/src/org/openqa/selenium/grid/sessionqueue/package-info.java new file mode 100644 index 0000000000000..48b760e8acc54 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/sessionqueue/package-info.java @@ -0,0 +1,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.grid.sessionqueue; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/sessionqueue/remote/BUILD.bazel b/java/src/org/openqa/selenium/grid/sessionqueue/remote/BUILD.bazel index 27ddf5111011e..85ead987f69c2 100644 --- a/java/src/org/openqa/selenium/grid/sessionqueue/remote/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/sessionqueue/remote/BUILD.bazel @@ -21,5 +21,6 @@ java_library( "//java/src/org/openqa/selenium/json", "//java/src/org/openqa/selenium/remote", artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/sessionqueue/remote/package-info.java b/java/src/org/openqa/selenium/grid/sessionqueue/remote/package-info.java new file mode 100644 index 0000000000000..723c8fecc9db8 --- /dev/null +++ b/java/src/org/openqa/selenium/grid/sessionqueue/remote/package-info.java @@ -0,0 +1,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.grid.sessionqueue.remote; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/grid/web/BUILD.bazel b/java/src/org/openqa/selenium/grid/web/BUILD.bazel index 6eccbb98ecbf4..b7893bca93ea9 100644 --- a/java/src/org/openqa/selenium/grid/web/BUILD.bazel +++ b/java/src/org/openqa/selenium/grid/web/BUILD.bazel @@ -16,5 +16,6 @@ java_library( "//java/src/org/openqa/selenium/remote", "//java/src/org/openqa/selenium/remote/http", artifact("com.google.guava:guava"), + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/src/org/openqa/selenium/grid/web/MergedResource.java b/java/src/org/openqa/selenium/grid/web/MergedResource.java index 15bc14912b693..fc43898b4d8d3 100644 --- a/java/src/org/openqa/selenium/grid/web/MergedResource.java +++ b/java/src/org/openqa/selenium/grid/web/MergedResource.java @@ -20,6 +20,7 @@ import java.util.HashSet; import java.util.Optional; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.internal.Require; public class MergedResource implements Resource { @@ -31,7 +32,7 @@ public MergedResource(Resource base) { this(base, null); } - private MergedResource(Resource base, Resource next) { + private MergedResource(Resource base, @Nullable Resource next) { this.base = Require.nonNull("Base resource", base); this.next = Optional.ofNullable(next); } diff --git a/java/src/org/openqa/selenium/grid/web/NoHandler.java b/java/src/org/openqa/selenium/grid/web/NoHandler.java index f8e18fa6fa881..68790ecda4e2c 100644 --- a/java/src/org/openqa/selenium/grid/web/NoHandler.java +++ b/java/src/org/openqa/selenium/grid/web/NoHandler.java @@ -26,6 +26,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.internal.Require; import org.openqa.selenium.json.Json; import org.openqa.selenium.remote.http.HttpHandler; @@ -43,7 +44,7 @@ public NoHandler(Json json) { @Override public HttpResponse execute(HttpRequest req) throws UncheckedIOException { // We're not using ImmutableMap for the outer map because it disallows null values. - Map responseMap = new HashMap<>(); + Map responseMap = new HashMap<>(); responseMap.put("sessionId", null); responseMap.put( "value", diff --git a/java/src/org/openqa/selenium/grid/web/Values.java b/java/src/org/openqa/selenium/grid/web/Values.java index a567bd80a81d4..009de95a68c1d 100644 --- a/java/src/org/openqa/selenium/grid/web/Values.java +++ b/java/src/org/openqa/selenium/grid/web/Values.java @@ -61,7 +61,7 @@ public static T get(HttpResponse response, Type typeOfT) { } } - throw new IllegalStateException("Unable to locate value: " + string(response)); + throw new IllegalStateException("Unable to locate value: " + response.contentAsString()); } catch (IOException e) { throw new UncheckedIOException(e); } diff --git a/java/src/org/openqa/selenium/grid/web/package-info.java b/java/src/org/openqa/selenium/grid/web/package-info.java new file mode 100644 index 0000000000000..b2760746de7da --- /dev/null +++ b/java/src/org/openqa/selenium/grid/web/package-info.java @@ -0,0 +1,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.grid.web; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/ie/InternetExplorerOptions.java b/java/src/org/openqa/selenium/ie/InternetExplorerOptions.java index 6f1c5ccc1c381..585bf376cedc3 100644 --- a/java/src/org/openqa/selenium/ie/InternetExplorerOptions.java +++ b/java/src/org/openqa/selenium/ie/InternetExplorerOptions.java @@ -89,7 +89,7 @@ public class InternetExplorerOptions extends AbstractDriverOptions ieOptions = new HashMap<>(); + private final Map ieOptions = new HashMap<>(); public InternetExplorerOptions() { setCapability(BROWSER_NAME, IE.browserName()); @@ -233,7 +233,7 @@ private InternetExplorerOptions amend(String optionName, Object value) { } @Override - public void setCapability(String key, Object value) { + public void setCapability(String key, @Nullable Object value) { if (IE_SWITCHES.equals(key)) { if (value instanceof List) { value = ((List) value).stream().map(Object::toString).collect(Collectors.joining(" ")); @@ -249,9 +249,9 @@ public void setCapability(String key, Object value) { if (IE_OPTIONS.equals(key)) { ieOptions.clear(); - Map streamFrom; + Map streamFrom; if (value instanceof Map) { - streamFrom = (Map) value; + streamFrom = (Map) value; } else if (value instanceof Capabilities) { streamFrom = ((Capabilities) value).asMap(); } else { diff --git a/java/src/org/openqa/selenium/internal/Debug.java b/java/src/org/openqa/selenium/internal/Debug.java index 5c694416f6890..c7786ccb7ff8d 100644 --- a/java/src/org/openqa/selenium/internal/Debug.java +++ b/java/src/org/openqa/selenium/internal/Debug.java @@ -29,7 +29,6 @@ public class Debug { private static final boolean IS_DEBUG; private static final AtomicBoolean DEBUG_WARNING_LOGGED = new AtomicBoolean(false); private static boolean loggerConfigured = false; - private static Logger seleniumLogger; static { IS_DEBUG = @@ -64,7 +63,7 @@ public static void configureLogger() { return; } - seleniumLogger = Logger.getLogger("org.openqa.selenium"); + Logger seleniumLogger = Logger.getLogger("org.openqa.selenium"); seleniumLogger.setLevel(Level.FINE); StreamHandler handler = new StreamHandler(System.err, new SimpleFormatter()); diff --git a/java/src/org/openqa/selenium/manager/BUILD.bazel b/java/src/org/openqa/selenium/manager/BUILD.bazel index d66cf5aa885ef..f0c3d396516e2 100644 --- a/java/src/org/openqa/selenium/manager/BUILD.bazel +++ b/java/src/org/openqa/selenium/manager/BUILD.bazel @@ -25,6 +25,7 @@ java_export( "//java/src/org/openqa/selenium:core", "//java/src/org/openqa/selenium/json", "//java/src/org/openqa/selenium/os", + "@maven//:org_jspecify_jspecify", ], ) diff --git a/java/src/org/openqa/selenium/manager/SeleniumManager.java b/java/src/org/openqa/selenium/manager/SeleniumManager.java index bed9e56e08dbe..e042b500c281f 100644 --- a/java/src/org/openqa/selenium/manager/SeleniumManager.java +++ b/java/src/org/openqa/selenium/manager/SeleniumManager.java @@ -36,6 +36,7 @@ import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.Beta; import org.openqa.selenium.BuildInfo; import org.openqa.selenium.Platform; @@ -70,9 +71,11 @@ public class SeleniumManager { private static final String EXE = ".exe"; private static final String SE_ENV_PREFIX = "SE_"; - private static volatile SeleniumManager manager; - private final String managerPath = System.getenv("SE_MANAGER_PATH"); - private Path binary = managerPath == null ? null : Paths.get(managerPath); + @Nullable private static volatile SeleniumManager manager; + + @Nullable private final String managerPath = System.getenv("SE_MANAGER_PATH"); + + @Nullable private Path binary = managerPath == null ? null : Paths.get(managerPath); private final String seleniumManagerVersion; private boolean binaryInTemporalFolder = false; diff --git a/java/src/org/openqa/selenium/manager/SeleniumManagerOutput.java b/java/src/org/openqa/selenium/manager/SeleniumManagerOutput.java index 80629dde4e676..74413ec5b0d66 100644 --- a/java/src/org/openqa/selenium/manager/SeleniumManagerOutput.java +++ b/java/src/org/openqa/selenium/manager/SeleniumManagerOutput.java @@ -20,14 +20,16 @@ import java.util.Locale; import java.util.Objects; import java.util.logging.Level; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.internal.Require; import org.openqa.selenium.json.JsonInput; public class SeleniumManagerOutput { - private List logs; - private Result result; + private @Nullable List logs; + private @Nullable Result result; + @Nullable public List getLogs() { return logs; } @@ -37,6 +39,7 @@ public SeleniumManagerOutput setLogs(List logs) { return this; } + @Nullable public Result getResult() { return result; } @@ -115,15 +118,19 @@ private static Log fromJson(JsonInput input) { public static class Result { private final int code; - private final String message; - private final String driverPath; - private final String browserPath; + private final @Nullable String message; + private final @Nullable String driverPath; + private final @Nullable String browserPath; public Result(String driverPath) { this(0, null, driverPath, null); } - public Result(int code, String message, String driverPath, String browserPath) { + public Result( + int code, + @Nullable String message, + @Nullable String driverPath, + @Nullable String browserPath) { this.code = code; this.message = message; this.driverPath = driverPath; @@ -134,14 +141,17 @@ public int getCode() { return code; } + @Nullable public String getMessage() { return message; } + @Nullable public String getDriverPath() { return driverPath; } + @Nullable public String getBrowserPath() { return browserPath; } diff --git a/java/src/org/openqa/selenium/manager/package-info.java b/java/src/org/openqa/selenium/manager/package-info.java new file mode 100644 index 0000000000000..48c3543b54a28 --- /dev/null +++ b/java/src/org/openqa/selenium/manager/package-info.java @@ -0,0 +1,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.manager; + +import org.jspecify.annotations.NullMarked; diff --git a/java/src/org/openqa/selenium/net/UrlChecker.java b/java/src/org/openqa/selenium/net/UrlChecker.java index 1392d3dc204b2..44437f2a463c8 100644 --- a/java/src/org/openqa/selenium/net/UrlChecker.java +++ b/java/src/org/openqa/selenium/net/UrlChecker.java @@ -31,6 +31,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Logger; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.io.Read; /** Polls a URL until a HTTP 200 response is received. */ @@ -59,7 +60,7 @@ public void waitUntilAvailable(long timeout, TimeUnit unit, final URL... urls) long start = System.currentTimeMillis(); LOG.fine("Waiting for " + Arrays.toString(urls)); try { - Future callback = + Future<@Nullable Void> callback = EXECUTOR.submit( () -> { HttpURLConnection connection = null; @@ -113,7 +114,7 @@ public void waitUntilUnavailable(long timeout, TimeUnit unit, final URL url) long start = System.currentTimeMillis(); LOG.fine("Waiting for " + url); try { - Future callback = + Future<@Nullable Void> callback = EXECUTOR.submit( () -> { HttpURLConnection connection = null; diff --git a/java/src/org/openqa/selenium/remote/AbstractDriverOptions.java b/java/src/org/openqa/selenium/remote/AbstractDriverOptions.java index 60c97d9befdeb..9017c3d4d9f75 100644 --- a/java/src/org/openqa/selenium/remote/AbstractDriverOptions.java +++ b/java/src/org/openqa/selenium/remote/AbstractDriverOptions.java @@ -34,6 +34,8 @@ import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.openqa.selenium.MutableCapabilities; import org.openqa.selenium.PageLoadStrategy; import org.openqa.selenium.Proxy; @@ -44,12 +46,12 @@ public abstract class AbstractDriverOptions extends MutableCapabilities { public DO setBrowserVersion(String browserVersion) { setCapability(BROWSER_VERSION, Require.nonNull("Browser version", browserVersion)); - return (DO) this; + return self(); } public DO setPlatformName(String platformName) { setCapability(PLATFORM_NAME, Require.nonNull("Platform Name", platformName)); - return (DO) this; + return self(); } public DO setImplicitWaitTimeout(Duration timeout) { @@ -57,7 +59,7 @@ public DO setImplicitWaitTimeout(Duration timeout) { timeouts.put("implicit", timeout.toMillis()); setCapability(TIMEOUTS, Collections.unmodifiableMap(timeouts)); - return (DO) this; + return self(); } public DO setPageLoadTimeout(Duration timeout) { @@ -65,7 +67,7 @@ public DO setPageLoadTimeout(Duration timeout) { timeouts.put("pageLoad", timeout.toMillis()); setCapability(TIMEOUTS, Collections.unmodifiableMap(timeouts)); - return (DO) this; + return self(); } public DO setScriptTimeout(Duration timeout) { @@ -73,37 +75,43 @@ public DO setScriptTimeout(Duration timeout) { timeouts.put("script", timeout.toMillis()); setCapability(TIMEOUTS, Collections.unmodifiableMap(timeouts)); - return (DO) this; + return self(); } public DO setPageLoadStrategy(PageLoadStrategy strategy) { setCapability(PAGE_LOAD_STRATEGY, Require.nonNull("Page load strategy", strategy)); - return (DO) this; + return self(); } public DO setUnhandledPromptBehaviour(UnexpectedAlertBehaviour behaviour) { setCapability( UNHANDLED_PROMPT_BEHAVIOUR, Require.nonNull("Unhandled prompt behavior", behaviour)); - return (DO) this; + return self(); } public DO setAcceptInsecureCerts(boolean acceptInsecureCerts) { setCapability(ACCEPT_INSECURE_CERTS, acceptInsecureCerts); - return (DO) this; + return self(); } public DO setStrictFileInteractability(boolean strictFileInteractability) { setCapability(STRICT_FILE_INTERACTABILITY, strictFileInteractability); - return (DO) this; + return self(); } public DO setProxy(Proxy proxy) { setCapability(PROXY, Require.nonNull("Proxy", proxy)); - return (DO) this; + return self(); } public DO setEnableDownloads(boolean enableDownloads) { setCapability(ENABLE_DOWNLOADS, enableDownloads); + return self(); + } + + @NonNull + @SuppressWarnings("unchecked") + private DO self() { return (DO) this; } @@ -126,6 +134,7 @@ public Object getCapability(String capabilityName) { return super.getCapability(capabilityName); } + @Nullable protected abstract Object getExtraCapability(String capabilityName); @Override diff --git a/java/src/org/openqa/selenium/remote/RemoteLogs.java b/java/src/org/openqa/selenium/remote/RemoteLogs.java index 75607fcd9a711..7d0f230d6b324 100644 --- a/java/src/org/openqa/selenium/remote/RemoteLogs.java +++ b/java/src/org/openqa/selenium/remote/RemoteLogs.java @@ -25,6 +25,7 @@ import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.stream.Collectors; import org.jspecify.annotations.Nullable; import org.openqa.selenium.Beta; import org.openqa.selenium.UnsupportedCommandException; @@ -111,18 +112,19 @@ private LogEntries getRemoteEntries(String logType) { } @SuppressWarnings("unchecked") List> rawList = (List>) raw; - List remoteEntries = new ArrayList<>(rawList.size()); + List remoteEntries = + rawList.stream().map(this::createLogEntry).collect(Collectors.toList()); - for (Map obj : rawList) { - remoteEntries.add( - new LogEntry( - LogLevelMapping.toLevel((String) obj.get(LEVEL)), - (Long) obj.get(TIMESTAMP), - (String) obj.get(MESSAGE))); - } return new LogEntries(remoteEntries); } + private LogEntry createLogEntry(Map obj) { + return new LogEntry( + LogLevelMapping.toLevel((String) obj.get(LEVEL)), + (Long) obj.get(TIMESTAMP), + (String) obj.get(MESSAGE)); + } + /** * @deprecated logging is not in the W3C WebDriver spec and LocalLogs are no longer supported. */ @@ -146,11 +148,9 @@ private Set getAvailableLocalLogs() { } @Override - @SuppressWarnings("deprecation") public Set getAvailableLogTypes() { - Object raw = executeMethod.execute(DriverCommand.GET_AVAILABLE_LOG_TYPES, null); - @SuppressWarnings("unchecked") - List rawList = (List) raw; + List rawList = + executeMethod.executeRequired(DriverCommand.GET_AVAILABLE_LOG_TYPES, null); Set builder = new LinkedHashSet<>(); builder.addAll(rawList); builder.addAll(getAvailableLocalLogs()); diff --git a/java/test/org/openqa/selenium/grid/config/BUILD.bazel b/java/test/org/openqa/selenium/grid/config/BUILD.bazel index 9575e42d240fb..a9584208da731 100644 --- a/java/test/org/openqa/selenium/grid/config/BUILD.bazel +++ b/java/test/org/openqa/selenium/grid/config/BUILD.bazel @@ -13,5 +13,6 @@ java_test_suite( artifact("com.google.guava:guava"), artifact("org.junit.jupiter:junit-jupiter-api"), artifact("org.assertj:assertj-core"), + artifact("org.jspecify:jspecify"), ] + JUNIT5_DEPS, ) diff --git a/java/test/org/openqa/selenium/grid/config/package-info.java b/java/test/org/openqa/selenium/grid/config/package-info.java new file mode 100644 index 0000000000000..f1393763f3149 --- /dev/null +++ b/java/test/org/openqa/selenium/grid/config/package-info.java @@ -0,0 +1,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.grid.config; + +import org.jspecify.annotations.NullMarked; diff --git a/java/test/org/openqa/selenium/grid/data/BUILD.bazel b/java/test/org/openqa/selenium/grid/data/BUILD.bazel index 8473abbb9e4e8..ac313a9987ae9 100644 --- a/java/test/org/openqa/selenium/grid/data/BUILD.bazel +++ b/java/test/org/openqa/selenium/grid/data/BUILD.bazel @@ -14,5 +14,6 @@ java_test_suite( artifact("com.google.guava:guava"), artifact("org.junit.jupiter:junit-jupiter-api"), artifact("org.assertj:assertj-core"), + artifact("org.jspecify:jspecify"), ] + JUNIT5_DEPS, ) diff --git a/java/test/org/openqa/selenium/grid/data/DefaultSlotMatcherTest.java b/java/test/org/openqa/selenium/grid/data/DefaultSlotMatcherTest.java index 7b5fb5562707a..99ca4a4c722ef 100644 --- a/java/test/org/openqa/selenium/grid/data/DefaultSlotMatcherTest.java +++ b/java/test/org/openqa/selenium/grid/data/DefaultSlotMatcherTest.java @@ -26,6 +26,7 @@ import org.openqa.selenium.Platform; import org.openqa.selenium.remote.CapabilityType; +@SuppressWarnings("EqualsWithItself") class DefaultSlotMatcherTest { private final DefaultSlotMatcher slotMatcher = new DefaultSlotMatcher(); diff --git a/java/test/org/openqa/selenium/grid/data/package-info.java b/java/test/org/openqa/selenium/grid/data/package-info.java new file mode 100644 index 0000000000000..578785a87ff4c --- /dev/null +++ b/java/test/org/openqa/selenium/grid/data/package-info.java @@ -0,0 +1,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.grid.data; + +import org.jspecify.annotations.NullMarked; diff --git a/java/test/org/openqa/selenium/grid/distributor/AddingNodesTest.java b/java/test/org/openqa/selenium/grid/distributor/AddingNodesTest.java index 67f88b7565410..685cc258952dd 100644 --- a/java/test/org/openqa/selenium/grid/distributor/AddingNodesTest.java +++ b/java/test/org/openqa/selenium/grid/distributor/AddingNodesTest.java @@ -35,6 +35,7 @@ import java.util.Set; import java.util.UUID; import java.util.function.Function; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.openqa.selenium.Capabilities; @@ -83,7 +84,7 @@ class AddingNodesTest { private static final Secret registrationSecret = new Secret("caerphilly"); private static final int newSessionThreadPoolSize = Runtime.getRuntime().availableProcessors(); - private Distributor distributor; + private @Nullable Distributor distributor; private Tracer tracer; private EventBus bus; private Wait wait; @@ -384,7 +385,7 @@ static class CustomNode extends Node { private final EventBus bus; private final Function factory; - private Session running; + private @Nullable Session running; protected CustomNode( EventBus bus, diff --git a/java/test/org/openqa/selenium/grid/distributor/BUILD.bazel b/java/test/org/openqa/selenium/grid/distributor/BUILD.bazel index 822b2bde76599..1e4728ddf8183 100644 --- a/java/test/org/openqa/selenium/grid/distributor/BUILD.bazel +++ b/java/test/org/openqa/selenium/grid/distributor/BUILD.bazel @@ -37,6 +37,7 @@ java_selenium_test_suite( artifact("org.assertj:assertj-core"), "//java/src/org/openqa/selenium:core", "//java/src/org/openqa/selenium/remote/http", + artifact("org.jspecify:jspecify"), ] + JUNIT5_DEPS, ) diff --git a/java/test/org/openqa/selenium/grid/distributor/local/BUILD.bazel b/java/test/org/openqa/selenium/grid/distributor/local/BUILD.bazel index 5cef7dac794cf..d43ed7e843143 100644 --- a/java/test/org/openqa/selenium/grid/distributor/local/BUILD.bazel +++ b/java/test/org/openqa/selenium/grid/distributor/local/BUILD.bazel @@ -32,5 +32,6 @@ java_test_suite( artifact("io.opentelemetry:opentelemetry-api"), artifact("org.junit.jupiter:junit-jupiter-api"), artifact("org.assertj:assertj-core"), + artifact("org.jspecify:jspecify"), ] + JUNIT5_DEPS, ) diff --git a/java/test/org/openqa/selenium/grid/distributor/local/LocalNodeRegistryTest.java b/java/test/org/openqa/selenium/grid/distributor/local/LocalNodeRegistryTest.java index 6db9833de7d4b..35e479d9160a1 100644 --- a/java/test/org/openqa/selenium/grid/distributor/local/LocalNodeRegistryTest.java +++ b/java/test/org/openqa/selenium/grid/distributor/local/LocalNodeRegistryTest.java @@ -86,6 +86,7 @@ void setUp() { } @AfterEach + @SuppressWarnings("ConstantValue") void tearDown() { if (registry != null) { registry.close(); diff --git a/java/test/org/openqa/selenium/grid/distributor/local/package-info.java b/java/test/org/openqa/selenium/grid/distributor/local/package-info.java new file mode 100644 index 0000000000000..29ed00ad32e30 --- /dev/null +++ b/java/test/org/openqa/selenium/grid/distributor/local/package-info.java @@ -0,0 +1,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.grid.distributor.local; + +import org.jspecify.annotations.NullMarked; diff --git a/java/test/org/openqa/selenium/grid/distributor/package-info.java b/java/test/org/openqa/selenium/grid/distributor/package-info.java new file mode 100644 index 0000000000000..6422c2c745391 --- /dev/null +++ b/java/test/org/openqa/selenium/grid/distributor/package-info.java @@ -0,0 +1,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.grid.distributor; + +import org.jspecify.annotations.NullMarked; diff --git a/java/test/org/openqa/selenium/grid/distributor/selector/BUILD.bazel b/java/test/org/openqa/selenium/grid/distributor/selector/BUILD.bazel index 6e87972283521..2ec64dbfc47a9 100644 --- a/java/test/org/openqa/selenium/grid/distributor/selector/BUILD.bazel +++ b/java/test/org/openqa/selenium/grid/distributor/selector/BUILD.bazel @@ -20,5 +20,6 @@ java_test_suite( artifact("com.google.guava:guava"), artifact("org.junit.jupiter:junit-jupiter-api"), artifact("org.assertj:assertj-core"), + artifact("org.jspecify:jspecify"), ] + JUNIT5_DEPS, ) diff --git a/java/test/org/openqa/selenium/grid/distributor/selector/package-info.java b/java/test/org/openqa/selenium/grid/distributor/selector/package-info.java new file mode 100644 index 0000000000000..0344710f634c2 --- /dev/null +++ b/java/test/org/openqa/selenium/grid/distributor/selector/package-info.java @@ -0,0 +1,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.grid.distributor.selector; + +import org.jspecify.annotations.NullMarked; diff --git a/java/test/org/openqa/selenium/grid/graphql/BUILD.bazel b/java/test/org/openqa/selenium/grid/graphql/BUILD.bazel index 083c1fcf84545..583baf073a2a1 100644 --- a/java/test/org/openqa/selenium/grid/graphql/BUILD.bazel +++ b/java/test/org/openqa/selenium/grid/graphql/BUILD.bazel @@ -33,5 +33,6 @@ java_test_suite( artifact("com.google.guava:guava"), artifact("org.junit.jupiter:junit-jupiter-api"), artifact("org.assertj:assertj-core"), + artifact("org.jspecify:jspecify"), ] + JUNIT5_DEPS, ) diff --git a/java/test/org/openqa/selenium/grid/graphql/package-info.java b/java/test/org/openqa/selenium/grid/graphql/package-info.java new file mode 100644 index 0000000000000..df07cd66175e3 --- /dev/null +++ b/java/test/org/openqa/selenium/grid/graphql/package-info.java @@ -0,0 +1,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.grid.graphql; + +import org.jspecify.annotations.NullMarked; diff --git a/java/test/org/openqa/selenium/grid/gridui/BUILD.bazel b/java/test/org/openqa/selenium/grid/gridui/BUILD.bazel index 9a6fa557a37de..ecd9c10e98b39 100644 --- a/java/test/org/openqa/selenium/grid/gridui/BUILD.bazel +++ b/java/test/org/openqa/selenium/grid/gridui/BUILD.bazel @@ -24,5 +24,6 @@ java_selenium_test_suite( artifact("com.google.guava:guava"), artifact("org.junit.jupiter:junit-jupiter-api"), artifact("org.assertj:assertj-core"), + artifact("org.jspecify:jspecify"), ] + JUNIT5_DEPS, ) diff --git a/java/test/org/openqa/selenium/grid/gridui/package-info.java b/java/test/org/openqa/selenium/grid/gridui/package-info.java new file mode 100644 index 0000000000000..bcfc99636f7e5 --- /dev/null +++ b/java/test/org/openqa/selenium/grid/gridui/package-info.java @@ -0,0 +1,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.grid.gridui; + +import org.jspecify.annotations.NullMarked; diff --git a/java/test/org/openqa/selenium/grid/node/BUILD.bazel b/java/test/org/openqa/selenium/grid/node/BUILD.bazel index 370858f09eeae..1d3ab581d282c 100644 --- a/java/test/org/openqa/selenium/grid/node/BUILD.bazel +++ b/java/test/org/openqa/selenium/grid/node/BUILD.bazel @@ -29,5 +29,6 @@ java_test_suite( artifact("org.junit.jupiter:junit-jupiter-api"), artifact("org.assertj:assertj-core"), artifact("org.mockito:mockito-core"), + artifact("org.jspecify:jspecify"), ] + JUNIT5_DEPS, ) diff --git a/java/test/org/openqa/selenium/grid/node/ProxyNodeWebsocketsTest.java b/java/test/org/openqa/selenium/grid/node/ProxyNodeWebsocketsTest.java index 70c2d17a18853..ac4fe45bfa1b9 100644 --- a/java/test/org/openqa/selenium/grid/node/ProxyNodeWebsocketsTest.java +++ b/java/test/org/openqa/selenium/grid/node/ProxyNodeWebsocketsTest.java @@ -26,6 +26,7 @@ import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.openqa.selenium.Capabilities; import org.openqa.selenium.ImmutableCapabilities; @@ -366,13 +367,13 @@ public boolean isReady() { private static class CountingStubNode extends StubNode { private final SessionId ownedSession; - private final Session session; + private final @Nullable Session session; private final AtomicInteger acquireCount; private final AtomicInteger releaseCount; CountingStubNode( SessionId ownedSession, - Session session, + @Nullable Session session, AtomicInteger acquireCount, AtomicInteger releaseCount) { super(new NodeId(UUID.randomUUID()), URI.create("http://localhost:5555")); @@ -400,6 +401,9 @@ public void releaseConnection(SessionId id) { @Override public Session getSession(SessionId id) { + if (session == null) { + throw new UnsupportedOperationException(); + } return session; } } diff --git a/java/test/org/openqa/selenium/grid/node/config/BUILD.bazel b/java/test/org/openqa/selenium/grid/node/config/BUILD.bazel index 95a52fb23cecd..9e078cb73af33 100644 --- a/java/test/org/openqa/selenium/grid/node/config/BUILD.bazel +++ b/java/test/org/openqa/selenium/grid/node/config/BUILD.bazel @@ -41,6 +41,7 @@ java_test_suite( artifact("org.assertj:assertj-core"), artifact("org.junit.jupiter:junit-jupiter-api"), artifact("org.mockito:mockito-core"), + artifact("org.jspecify:jspecify"), ] + JUNIT5_DEPS, ) @@ -77,5 +78,6 @@ java_test_suite( artifact("org.assertj:assertj-core"), artifact("org.junit.jupiter:junit-jupiter-api"), artifact("org.mockito:mockito-core"), + artifact("org.jspecify:jspecify"), ] + JUNIT5_DEPS, ) diff --git a/java/test/org/openqa/selenium/grid/node/config/SessionCapabilitiesMutatorTest.java b/java/test/org/openqa/selenium/grid/node/config/SessionCapabilitiesMutatorTest.java index 527860fc38d0a..b1e3a808b296f 100644 --- a/java/test/org/openqa/selenium/grid/node/config/SessionCapabilitiesMutatorTest.java +++ b/java/test/org/openqa/selenium/grid/node/config/SessionCapabilitiesMutatorTest.java @@ -32,24 +32,20 @@ import org.openqa.selenium.ImmutableCapabilities; public class SessionCapabilitiesMutatorTest { - - private SessionCapabilitiesMutator sessionCapabilitiesMutator; - private Capabilities stereotype; - private Capabilities capabilities; - @Test void shouldMergeStereotypeWithoutOptionsWithCapsWithOptions() { - stereotype = + Capabilities stereotype = new ImmutableCapabilities( "browserName", "chrome", "unhandledPromptBehavior", "accept"); - sessionCapabilitiesMutator = new SessionCapabilitiesMutator(stereotype); + SessionCapabilitiesMutator sessionCapabilitiesMutator = + new SessionCapabilitiesMutator(stereotype); Map chromeOptions = new HashMap<>(); chromeOptions.put("args", List.of("incognito", "window-size=500,500")); - capabilities = + Capabilities capabilities = new ImmutableCapabilities( "browserName", "chrome", "goog:chromeOptions", chromeOptions, @@ -74,15 +70,16 @@ void shouldMergeStereotypeWithOptionsWithCapsWithoutOptions() { Map chromeOptions = new HashMap<>(); chromeOptions.put("args", List.of("incognito", "window-size=500,500")); - stereotype = + Capabilities stereotype = new ImmutableCapabilities( "browserName", "chrome", "goog:chromeOptions", chromeOptions, "unhandledPromptBehavior", "accept"); - sessionCapabilitiesMutator = new SessionCapabilitiesMutator(stereotype); + SessionCapabilitiesMutator sessionCapabilitiesMutator = + new SessionCapabilitiesMutator(stereotype); - capabilities = + Capabilities capabilities = new ImmutableCapabilities( "browserName", "chrome", "pageLoadStrategy", "normal"); @@ -113,10 +110,11 @@ void shouldMergeChromeSpecificOptionsFromStereotypeAndCaps() { stereotypeOptions.put("opt1", "val1"); stereotypeOptions.put("opt2", "val4"); - stereotype = + Capabilities stereotype = new ImmutableCapabilities("browserName", "chrome", "goog:chromeOptions", stereotypeOptions); - sessionCapabilitiesMutator = new SessionCapabilitiesMutator(stereotype); + SessionCapabilitiesMutator sessionCapabilitiesMutator = + new SessionCapabilitiesMutator(stereotype); Map capabilityOptions = new HashMap<>(); capabilityOptions.put("args", List.of("incognito", "--headless")); @@ -125,7 +123,7 @@ void shouldMergeChromeSpecificOptionsFromStereotypeAndCaps() { capabilityOptions.put("opt2", "val2"); capabilityOptions.put("opt3", "val3"); - capabilities = + Capabilities capabilities = new ImmutableCapabilities("browserName", "chrome", "goog:chromeOptions", capabilityOptions); Map modifiedCapabilities = @@ -171,11 +169,12 @@ void shouldMergeEdgeSpecificOptionsFromStereotypeAndCaps() { stereotypeOptions.put("opt1", "val1"); stereotypeOptions.put("opt2", "val4"); - stereotype = + Capabilities stereotype = new ImmutableCapabilities( "browserName", "microsoftedge", "ms:edgeOptions", stereotypeOptions); - sessionCapabilitiesMutator = new SessionCapabilitiesMutator(stereotype); + SessionCapabilitiesMutator sessionCapabilitiesMutator = + new SessionCapabilitiesMutator(stereotype); Map capabilityOptions = new HashMap<>(); capabilityOptions.put("args", List.of("incognito", "--headless")); @@ -184,7 +183,7 @@ void shouldMergeEdgeSpecificOptionsFromStereotypeAndCaps() { capabilityOptions.put("opt2", "val2"); capabilityOptions.put("opt3", "val3"); - capabilities = + Capabilities capabilities = new ImmutableCapabilities( "browserName", "microsoftedge", "ms:edgeOptions", capabilityOptions); @@ -237,11 +236,12 @@ void shouldMergeFirefoxSpecificOptionsFromStereotypeAndCaps() { stereotypeOptions.put("profile", "profile-string"); stereotypeOptions.put("androidDeviceSerial", "emulator-5556"); - stereotype = + Capabilities stereotype = new ImmutableCapabilities( "browserName", "firefox", "moz:firefoxOptions", stereotypeOptions); - sessionCapabilitiesMutator = new SessionCapabilitiesMutator(stereotype); + SessionCapabilitiesMutator sessionCapabilitiesMutator = + new SessionCapabilitiesMutator(stereotype); Map capabilityOptions = new HashMap<>(); capabilityOptions.put("args", Collections.singletonList("-headless")); @@ -260,7 +260,7 @@ void shouldMergeFirefoxSpecificOptionsFromStereotypeAndCaps() { capabilityOptions.put("binary", "/path/to/caps/binary"); capabilityOptions.put("androidPackage", "com.android.chrome"); - capabilities = + Capabilities capabilities = new ImmutableCapabilities( "browserName", "firefox", "moz:firefoxOptions", capabilityOptions); @@ -321,15 +321,16 @@ void shouldMergeFirefoxSpecificOptionsFromStereotypeAndCaps() { @Test void shouldMergeTopLevelStereotypeAndCaps() { - stereotype = + Capabilities stereotype = new ImmutableCapabilities( "browserName", "chrome", "unhandledPromptBehavior", "accept", "pageLoadStrategy", "eager"); - sessionCapabilitiesMutator = new SessionCapabilitiesMutator(stereotype); + SessionCapabilitiesMutator sessionCapabilitiesMutator = + new SessionCapabilitiesMutator(stereotype); - capabilities = + Capabilities capabilities = new ImmutableCapabilities( "browserName", "chrome", "pageLoadStrategy", "normal"); @@ -344,11 +345,12 @@ void shouldMergeTopLevelStereotypeAndCaps() { @Test void shouldAllowUnknownBrowserNames() { - stereotype = new ImmutableCapabilities("browserName", "safari"); + Capabilities stereotype = new ImmutableCapabilities("browserName", "safari"); - sessionCapabilitiesMutator = new SessionCapabilitiesMutator(stereotype); + SessionCapabilitiesMutator sessionCapabilitiesMutator = + new SessionCapabilitiesMutator(stereotype); - capabilities = new ImmutableCapabilities("browserName", "safari"); + Capabilities capabilities = new ImmutableCapabilities("browserName", "safari"); Map modifiedCapabilities = sessionCapabilitiesMutator.apply(capabilities).asMap(); diff --git a/java/test/org/openqa/selenium/grid/node/config/package-info.java b/java/test/org/openqa/selenium/grid/node/config/package-info.java new file mode 100644 index 0000000000000..51df08ff26d59 --- /dev/null +++ b/java/test/org/openqa/selenium/grid/node/config/package-info.java @@ -0,0 +1,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.grid.node.config; + +import org.jspecify.annotations.NullMarked; diff --git a/java/test/org/openqa/selenium/grid/node/data/BUILD.bazel b/java/test/org/openqa/selenium/grid/node/data/BUILD.bazel index ae130811e9ee7..c38143bf3639f 100644 --- a/java/test/org/openqa/selenium/grid/node/data/BUILD.bazel +++ b/java/test/org/openqa/selenium/grid/node/data/BUILD.bazel @@ -1,3 +1,4 @@ +load("@rules_jvm_external//:defs.bzl", "artifact") load("//java:defs.bzl", "java_library") java_library( @@ -13,5 +14,6 @@ java_library( "//java/src/org/openqa/selenium/grid/security", "//java/src/org/openqa/selenium/json", "//java/src/org/openqa/selenium/remote", + artifact("org.jspecify:jspecify"), ], ) diff --git a/java/test/org/openqa/selenium/grid/node/data/package-info.java b/java/test/org/openqa/selenium/grid/node/data/package-info.java new file mode 100644 index 0000000000000..660d3c87372f7 --- /dev/null +++ b/java/test/org/openqa/selenium/grid/node/data/package-info.java @@ -0,0 +1,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.grid.node.data; + +import org.jspecify.annotations.NullMarked; diff --git a/java/test/org/openqa/selenium/grid/node/docker/BUILD.bazel b/java/test/org/openqa/selenium/grid/node/docker/BUILD.bazel index 9704b17e181ae..f83a1e10e8086 100644 --- a/java/test/org/openqa/selenium/grid/node/docker/BUILD.bazel +++ b/java/test/org/openqa/selenium/grid/node/docker/BUILD.bazel @@ -19,5 +19,6 @@ java_test_suite( artifact("org.junit.jupiter:junit-jupiter-params"), artifact("org.assertj:assertj-core"), artifact("org.mockito:mockito-core"), + artifact("org.jspecify:jspecify"), ] + JUNIT5_DEPS, ) diff --git a/java/test/org/openqa/selenium/grid/node/docker/package-info.java b/java/test/org/openqa/selenium/grid/node/docker/package-info.java new file mode 100644 index 0000000000000..b2e9f6b6b6b1b --- /dev/null +++ b/java/test/org/openqa/selenium/grid/node/docker/package-info.java @@ -0,0 +1,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.grid.node.docker; + +import org.jspecify.annotations.NullMarked; diff --git a/java/test/org/openqa/selenium/grid/node/kubernetes/BUILD.bazel b/java/test/org/openqa/selenium/grid/node/kubernetes/BUILD.bazel index d7deafd35677b..3cabfda65c9e6 100644 --- a/java/test/org/openqa/selenium/grid/node/kubernetes/BUILD.bazel +++ b/java/test/org/openqa/selenium/grid/node/kubernetes/BUILD.bazel @@ -19,5 +19,6 @@ java_test_suite( artifact("org.junit.jupiter:junit-jupiter-api"), artifact("org.assertj:assertj-core"), artifact("org.mockito:mockito-core"), + artifact("org.jspecify:jspecify"), ] + JUNIT5_DEPS, ) diff --git a/java/test/org/openqa/selenium/grid/node/kubernetes/package-info.java b/java/test/org/openqa/selenium/grid/node/kubernetes/package-info.java new file mode 100644 index 0000000000000..6f37afbf08e4c --- /dev/null +++ b/java/test/org/openqa/selenium/grid/node/kubernetes/package-info.java @@ -0,0 +1,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.grid.node.kubernetes; + +import org.jspecify.annotations.NullMarked; diff --git a/java/test/org/openqa/selenium/grid/node/local/BUILD.bazel b/java/test/org/openqa/selenium/grid/node/local/BUILD.bazel index 687a49de94817..98a0f03219f32 100644 --- a/java/test/org/openqa/selenium/grid/node/local/BUILD.bazel +++ b/java/test/org/openqa/selenium/grid/node/local/BUILD.bazel @@ -20,5 +20,6 @@ java_test_suite( artifact("io.opentelemetry:opentelemetry-api"), artifact("org.junit.jupiter:junit-jupiter-api"), artifact("org.assertj:assertj-core"), + artifact("org.jspecify:jspecify"), ] + JUNIT5_DEPS, ) diff --git a/java/test/org/openqa/selenium/grid/node/local/package-info.java b/java/test/org/openqa/selenium/grid/node/local/package-info.java new file mode 100644 index 0000000000000..f47f0602b0030 --- /dev/null +++ b/java/test/org/openqa/selenium/grid/node/local/package-info.java @@ -0,0 +1,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.grid.node.local; + +import org.jspecify.annotations.NullMarked; diff --git a/java/test/org/openqa/selenium/grid/node/package-info.java b/java/test/org/openqa/selenium/grid/node/package-info.java new file mode 100644 index 0000000000000..f858c033d8a46 --- /dev/null +++ b/java/test/org/openqa/selenium/grid/node/package-info.java @@ -0,0 +1,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.grid.node; + +import org.jspecify.annotations.NullMarked; diff --git a/java/test/org/openqa/selenium/grid/node/relay/BUILD.bazel b/java/test/org/openqa/selenium/grid/node/relay/BUILD.bazel index 274b85c1c6869..f9a1525fc7fef 100644 --- a/java/test/org/openqa/selenium/grid/node/relay/BUILD.bazel +++ b/java/test/org/openqa/selenium/grid/node/relay/BUILD.bazel @@ -17,5 +17,6 @@ java_test_suite( artifact("org.junit.jupiter:junit-jupiter-api"), artifact("org.assertj:assertj-core"), artifact("org.mockito:mockito-core"), + artifact("org.jspecify:jspecify"), ] + JUNIT5_DEPS, ) diff --git a/java/test/org/openqa/selenium/grid/node/relay/package-info.java b/java/test/org/openqa/selenium/grid/node/relay/package-info.java new file mode 100644 index 0000000000000..d0133b3427817 --- /dev/null +++ b/java/test/org/openqa/selenium/grid/node/relay/package-info.java @@ -0,0 +1,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.grid.node.relay; + +import org.jspecify.annotations.NullMarked; diff --git a/java/test/org/openqa/selenium/grid/router/BUILD.bazel b/java/test/org/openqa/selenium/grid/router/BUILD.bazel index 33ca056590d9b..3dfb296f47f56 100644 --- a/java/test/org/openqa/selenium/grid/router/BUILD.bazel +++ b/java/test/org/openqa/selenium/grid/router/BUILD.bazel @@ -38,6 +38,7 @@ java_library( "//java/src/org/openqa/selenium/remote/http", "//java/src/org/openqa/selenium/support", "//java/test/org/openqa/selenium/testing:test-base", + artifact("org.jspecify:jspecify"), ], ) @@ -67,6 +68,7 @@ java_selenium_test_suite( artifact("org.junit.jupiter:junit-jupiter-api"), artifact("org.junit.jupiter:junit-jupiter-params"), artifact("org.assertj:assertj-core"), + artifact("org.jspecify:jspecify"), ] + CDP_DEPS + JUNIT5_DEPS, ) @@ -98,6 +100,7 @@ java_selenium_test_suite( artifact("org.junit.jupiter:junit-jupiter-api"), artifact("org.junit.jupiter:junit-jupiter-params"), artifact("org.assertj:assertj-core"), + artifact("org.jspecify:jspecify"), ] + CDP_DEPS + JUNIT5_DEPS, ) @@ -120,6 +123,7 @@ java_selenium_test_suite( "//java/test/org/openqa/selenium/testing:test-base", artifact("org.junit.jupiter:junit-jupiter-api"), artifact("org.assertj:assertj-core"), + artifact("org.jspecify:jspecify"), ] + CDP_DEPS + JUNIT5_DEPS, ) @@ -156,5 +160,6 @@ java_test_suite( artifact("org.junit.jupiter:junit-jupiter-params"), artifact("org.assertj:assertj-core"), artifact("org.zeromq:jeromq"), + artifact("org.jspecify:jspecify"), ] + JUNIT5_DEPS, ) diff --git a/java/test/org/openqa/selenium/grid/router/RemoteWebDriverBiDiTest.java b/java/test/org/openqa/selenium/grid/router/RemoteWebDriverBiDiTest.java index fe507998dfbab..8b19e34e3ce03 100644 --- a/java/test/org/openqa/selenium/grid/router/RemoteWebDriverBiDiTest.java +++ b/java/test/org/openqa/selenium/grid/router/RemoteWebDriverBiDiTest.java @@ -80,6 +80,7 @@ void setup() { } @AfterEach + @SuppressWarnings("ConstantValue") void tearDownDeployment() { if (localDriver != null) { localDriver.quit(); diff --git a/java/test/org/openqa/selenium/grid/router/SessionCleanUpTest.java b/java/test/org/openqa/selenium/grid/router/SessionCleanUpTest.java index 623e9656959d9..3eaf57162f4fc 100644 --- a/java/test/org/openqa/selenium/grid/router/SessionCleanUpTest.java +++ b/java/test/org/openqa/selenium/grid/router/SessionCleanUpTest.java @@ -119,6 +119,7 @@ public void setup() { } @AfterEach + @SuppressWarnings("ConstantValue") public void stopServer() { if (server != null) { server.stop(); diff --git a/java/test/org/openqa/selenium/grid/router/package-info.java b/java/test/org/openqa/selenium/grid/router/package-info.java new file mode 100644 index 0000000000000..1ed3dadc439f8 --- /dev/null +++ b/java/test/org/openqa/selenium/grid/router/package-info.java @@ -0,0 +1,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.grid.router; + +import org.jspecify.annotations.NullMarked; diff --git a/java/test/org/openqa/selenium/grid/security/BUILD.bazel b/java/test/org/openqa/selenium/grid/security/BUILD.bazel index e0c6b83987074..7e75330e3d60a 100644 --- a/java/test/org/openqa/selenium/grid/security/BUILD.bazel +++ b/java/test/org/openqa/selenium/grid/security/BUILD.bazel @@ -9,5 +9,6 @@ java_test_suite( "//java/src/org/openqa/selenium/remote/http", artifact("org.junit.jupiter:junit-jupiter-api"), artifact("org.assertj:assertj-core"), + artifact("org.jspecify:jspecify"), ] + JUNIT5_DEPS, ) diff --git a/java/test/org/openqa/selenium/grid/security/package-info.java b/java/test/org/openqa/selenium/grid/security/package-info.java new file mode 100644 index 0000000000000..29b62cab27d5a --- /dev/null +++ b/java/test/org/openqa/selenium/grid/security/package-info.java @@ -0,0 +1,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.grid.security; + +import org.jspecify.annotations.NullMarked; diff --git a/java/test/org/openqa/selenium/grid/server/BUILD.bazel b/java/test/org/openqa/selenium/grid/server/BUILD.bazel index 2cf09abe9c814..fc7965c8ddded 100644 --- a/java/test/org/openqa/selenium/grid/server/BUILD.bazel +++ b/java/test/org/openqa/selenium/grid/server/BUILD.bazel @@ -21,5 +21,6 @@ java_test_suite( artifact("com.google.guava:guava"), artifact("org.junit.jupiter:junit-jupiter-api"), artifact("org.assertj:assertj-core"), + artifact("org.jspecify:jspecify"), ] + JUNIT5_DEPS, ) diff --git a/java/test/org/openqa/selenium/grid/server/package-info.java b/java/test/org/openqa/selenium/grid/server/package-info.java new file mode 100644 index 0000000000000..adecd3fa97fd3 --- /dev/null +++ b/java/test/org/openqa/selenium/grid/server/package-info.java @@ -0,0 +1,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.grid.server; + +import org.jspecify.annotations.NullMarked; diff --git a/java/test/org/openqa/selenium/remote/RemoteLogsTest.java b/java/test/org/openqa/selenium/remote/RemoteLogsTest.java index 49201de14c0aa..e9044760a0e93 100644 --- a/java/test/org/openqa/selenium/remote/RemoteLogsTest.java +++ b/java/test/org/openqa/selenium/remote/RemoteLogsTest.java @@ -133,7 +133,7 @@ void throwsOnBogusRemoteLogsResponse() { @Test void canGetAvailableLogTypes() { List remoteAvailableLogTypes = List.of(LogType.PROFILER, LogType.SERVER); - when(executeMethod.execute(DriverCommand.GET_AVAILABLE_LOG_TYPES, null)) + when(executeMethod.executeRequired(DriverCommand.GET_AVAILABLE_LOG_TYPES, null)) .thenReturn(remoteAvailableLogTypes); Set localAvailableLogTypes = Set.of(LogType.PROFILER, LogType.CLIENT);