This is an automated email from the ASF dual-hosted git repository.
He-Pin pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/pekko.git
The following commit(s) were added to refs/heads/main by this push:
new 05efd55a73 feat: add jspecify null-safety annotations to actor-typed,
cluster-sharding-typed, and testkit javadsl (#3380)
05efd55a73 is described below
commit 05efd55a73085326fbd36e69757693565b7844d1
Author: He-Pin(kerr) <[email protected]>
AuthorDate: Sat Jul 25 23:13:53 2026 +0800
feat: add jspecify null-safety annotations to actor-typed,
cluster-sharding-typed, and testkit javadsl (#3380)
Motivation:
Extend jspecify coverage to remaining Java DSL modules (#2563),
following the pattern established in streams (#2617) and persistence
(#2850).
Modification:
- Add @NullMarked package-info.java for actor-typed, cluster-sharding-typed,
and testkit javadsl packages
- Add @Nullable to Behaviors.withMdc staticMdc and mdcForMessage parameters
(both explicitly checked for null in implementation)
- Add @Nullable to Entity.with* methods in ClusterSharding
(all wrapped in Optional.ofNullable, explicitly accepting null)
- Add jspecify dependency to actorTyped, testkit, and clusterShardingTyped
modules
Result:
Java consumers get null-safety signals via JSpecify annotations for
actor-typed, cluster-sharding-typed, and testkit Java DSLs.
Tests:
- sbt actor-typed/compile testkit/compile cluster-sharding-typed/compile
- sbt actor-typed-tests/testOnly org.apache.pekko.actor.typed.javadsl.*
- sbt actor-typed/mimaReportBinaryIssues testkit/mimaReportBinaryIssues
cluster-sharding-typed/mimaReportBinaryIssues
- sbt actor-typed/headerCheck testkit/headerCheck
cluster-sharding-typed/headerCheck
- scalafmt --mode diff-ref=origin/main
- git diff --check
References:
Refs #2563
---
.../pekko/actor/typed/javadsl/package-info.java | 25 ++++++++++++++++++++++
.../pekko/actor/typed/javadsl/Behaviors.scala | 6 ++++--
build.sbt | 1 +
.../sharding/typed/javadsl/package-info.java | 25 ++++++++++++++++++++++
.../sharding/typed/javadsl/ClusterSharding.scala | 16 ++++++++------
project/Dependencies.scala | 5 ++++-
.../apache/pekko/testkit/javadsl/package-info.java | 25 ++++++++++++++++++++++
7 files changed, 94 insertions(+), 9 deletions(-)
diff --git
a/actor-typed/src/main/java/org/apache/pekko/actor/typed/javadsl/package-info.java
b/actor-typed/src/main/java/org/apache/pekko/actor/typed/javadsl/package-info.java
new file mode 100644
index 0000000000..04216dd906
--- /dev/null
+++
b/actor-typed/src/main/java/org/apache/pekko/actor/typed/javadsl/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.
+ */
+
+/**
+ * Java API for Pekko Actor Typed.
+ *
+ * <p>This package contains the Java DSL for Pekko Actor Typed. For the Scala
DSL see {@code
+ * org.apache.pekko.actor.typed.scaladsl}.
+ */
[email protected]
+package org.apache.pekko.actor.typed.javadsl;
diff --git
a/actor-typed/src/main/scala/org/apache/pekko/actor/typed/javadsl/Behaviors.scala
b/actor-typed/src/main/scala/org/apache/pekko/actor/typed/javadsl/Behaviors.scala
index 41e8a8b678..6353ea1856 100644
---
a/actor-typed/src/main/scala/org/apache/pekko/actor/typed/javadsl/Behaviors.scala
+++
b/actor-typed/src/main/scala/org/apache/pekko/actor/typed/javadsl/Behaviors.scala
@@ -20,6 +20,8 @@ import scala.annotation.nowarn
import scala.jdk.CollectionConverters._
import scala.reflect.ClassTag
+import org.jspecify.annotations.Nullable
+
import org.apache.pekko
import pekko.actor.typed._
import pekko.actor.typed.internal.{ BehaviorImpl, StashBufferImpl,
TimerSchedulerImpl, WithMdcBehaviorInterceptor }
@@ -402,8 +404,8 @@ object Behaviors {
*/
def withMdc[T](
interceptMessageClass: Class[T],
- staticMdc: java.util.Map[String, String],
- mdcForMessage: pekko.japi.function.Function[T, java.util.Map[String,
String]],
+ @Nullable staticMdc: java.util.Map[String, String],
+ @Nullable mdcForMessage: pekko.japi.function.Function[T,
java.util.Map[String, String]],
behavior: Behavior[T]): Behavior[T] = {
def asScalaMap(m: java.util.Map[String, String]): Map[String, String] = {
diff --git a/build.sbt b/build.sbt
index b283f1f66e..0d5f03cc68 100644
--- a/build.sbt
+++ b/build.sbt
@@ -575,6 +575,7 @@ lazy val clusterShardingTyped =
pekkoModule("cluster-sharding-typed")
remoteTests % "test->test",
remoteTests % "test->test;multi-jvm->multi-jvm",
jackson % "test->test")
+ .settings(Dependencies.clusterShardingTyped)
.settings(javacOptions += "-parameters") // for Jackson
.settings(AutomaticModuleName.settings("pekko.cluster.sharding.typed"))
// To be able to import ContainerFormats.proto
diff --git
a/cluster-sharding-typed/src/main/java/org/apache/pekko/cluster/sharding/typed/javadsl/package-info.java
b/cluster-sharding-typed/src/main/java/org/apache/pekko/cluster/sharding/typed/javadsl/package-info.java
new file mode 100644
index 0000000000..19ef9b5860
--- /dev/null
+++
b/cluster-sharding-typed/src/main/java/org/apache/pekko/cluster/sharding/typed/javadsl/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.
+ */
+
+/**
+ * Java API for Pekko Cluster Sharding Typed.
+ *
+ * <p>This package contains the Java DSL for Pekko Cluster Sharding Typed. For
the Scala DSL see
+ * {@code org.apache.pekko.cluster.sharding.typed.scaladsl}.
+ */
[email protected]
+package org.apache.pekko.cluster.sharding.typed.javadsl;
diff --git
a/cluster-sharding-typed/src/main/scala/org/apache/pekko/cluster/sharding/typed/javadsl/ClusterSharding.scala
b/cluster-sharding-typed/src/main/scala/org/apache/pekko/cluster/sharding/typed/javadsl/ClusterSharding.scala
index dcdd8b36be..b9ebc34d7f 100644
---
a/cluster-sharding-typed/src/main/scala/org/apache/pekko/cluster/sharding/typed/javadsl/ClusterSharding.scala
+++
b/cluster-sharding-typed/src/main/scala/org/apache/pekko/cluster/sharding/typed/javadsl/ClusterSharding.scala
@@ -21,6 +21,8 @@ import java.util.concurrent.CompletionStage
import scala.annotation.nowarn
import scala.jdk.OptionConverters._
+import org.jspecify.annotations.Nullable
+
import org.apache.pekko
import pekko.actor.typed.ActorRef
import pekko.actor.typed.ActorSystem
@@ -279,7 +281,7 @@ final class Entity[M, E] private (
/**
* Additional settings, typically loaded from configuration.
*/
- def withSettings(newSettings: ClusterShardingSettings): Entity[M, E] =
+ def withSettings(@Nullable newSettings: ClusterShardingSettings): Entity[M,
E] =
copy(settings = Optional.ofNullable(newSettings))
/**
@@ -288,7 +290,7 @@ final class Entity[M, E] private (
* It can be useful to define a custom stop message if the entity needs to
perform
* some asynchronous cleanup or interactions before stopping.
*/
- def withStopMessage(newStopMessage: M): Entity[M, E] =
+ def withStopMessage(@Nullable newStopMessage: M): Entity[M, E] =
copy(stopMessage = Optional.ofNullable(newStopMessage))
/**
@@ -298,7 +300,8 @@ final class Entity[M, E] private (
* shards is then defined by `numberOfShards` in `ClusterShardingSettings`,
which by default
* is configured with `pekko.cluster.sharding.number-of-shards`.
*/
- def withMessageExtractor[Envelope](newExtractor:
ShardingMessageExtractor[Envelope, M]): Entity[M, Envelope] =
+ def withMessageExtractor[Envelope](
+ @Nullable newExtractor: ShardingMessageExtractor[Envelope, M]):
Entity[M, Envelope] =
new Entity(
createBehavior,
typeKey,
@@ -313,7 +316,7 @@ final class Entity[M, E] private (
/**
* Run the Entity actors on nodes with the given role.
*/
- def withRole(role: String): Entity[M, E] =
+ def withRole(@Nullable role: String): Entity[M, E] =
copy(role = Optional.ofNullable(role))
/**
@@ -322,13 +325,14 @@ final class Entity[M, E] private (
* dataCenter does not match the data center of the current node the
`ShardRegion` will be started
* in proxy mode.
*/
- def withDataCenter(newDataCenter: String): Entity[M, E] = copy(dataCenter =
Optional.ofNullable(newDataCenter))
+ def withDataCenter(@Nullable newDataCenter: String): Entity[M, E] =
+ copy(dataCenter = Optional.ofNullable(newDataCenter))
/**
* Allocation strategy which decides on which nodes to allocate new shards,
* [[ClusterSharding#defaultShardAllocationStrategy]] is used if this is not
specified.
*/
- def withAllocationStrategy(newAllocationStrategy: ShardAllocationStrategy):
Entity[M, E] =
+ def withAllocationStrategy(@Nullable newAllocationStrategy:
ShardAllocationStrategy): Entity[M, E] =
copy(allocationStrategy = Optional.ofNullable(newAllocationStrategy))
private def copy(
diff --git a/project/Dependencies.scala b/project/Dependencies.scala
index c496833ab2..d491208e45 100644
--- a/project/Dependencies.scala
+++ b/project/Dependencies.scala
@@ -214,13 +214,14 @@ object Dependencies {
lazy val actor = l ++= Seq(config)
- val actorTyped = l ++= Seq(slf4jApi)
+ val actorTyped = l ++= Seq(slf4jApi, jspecify)
val discovery = l ++= Seq(TestDependencies.junit, TestDependencies.scalatest)
val coordination = l ++= Seq(TestDependencies.junit,
TestDependencies.scalatest)
val testkit = l ++= Seq(
+ jspecify,
TestDependencies.junit,
TestDependencies.junit6,
TestDependencies.junitPlatformLauncher,
@@ -278,6 +279,8 @@ object Dependencies {
TestDependencies.commonsIo,
TestDependencies.ycsb)
+ lazy val clusterShardingTyped = l ++= Seq(jspecify)
+
lazy val clusterMetrics = l ++= Seq(
Provided.sigarLoader,
TestDependencies.slf4jJul,
diff --git
a/testkit/src/main/java/org/apache/pekko/testkit/javadsl/package-info.java
b/testkit/src/main/java/org/apache/pekko/testkit/javadsl/package-info.java
new file mode 100644
index 0000000000..2050f72546
--- /dev/null
+++ b/testkit/src/main/java/org/apache/pekko/testkit/javadsl/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.
+ */
+
+/**
+ * Java API for Pekko TestKit.
+ *
+ * <p>This package contains the Java DSL for Pekko TestKit. For the Scala DSL
see {@code
+ * org.apache.pekko.testkit}.
+ */
[email protected]
+package org.apache.pekko.testkit.javadsl;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]