diff --git a/static-analysis-modules/jspecify-nullsafety/pom.xml b/static-analysis-modules/jspecify-nullsafety/pom.xml
new file mode 100644
index 000000000000..f36955b151c4
--- /dev/null
+++ b/static-analysis-modules/jspecify-nullsafety/pom.xml
@@ -0,0 +1,24 @@
+
+
+ 4.0.0
+ jspecify-nullsafety
+ jar
+ core-java-8-datetime-3
+
+
+ com.baeldung
+ static-analysis-modules
+ 1.0-SNAPSHOT
+
+
+
+
+ org.jspecify
+ jspecify
+ 0.3.0
+
+
+
+
\ No newline at end of file
diff --git a/static-analysis-modules/jspecify-nullsafety/src/test/java/com/baeldung/jspecify/JspecifyNullSafetyTest.java b/static-analysis-modules/jspecify-nullsafety/src/test/java/com/baeldung/jspecify/JspecifyNullSafetyTest.java
new file mode 100644
index 000000000000..237028970b5b
--- /dev/null
+++ b/static-analysis-modules/jspecify-nullsafety/src/test/java/com/baeldung/jspecify/JspecifyNullSafetyTest.java
@@ -0,0 +1,76 @@
+package com.baeldung.jspecify;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Objects;
+import java.util.Optional;
+
+import org.jspecify.annotations.Nullable;
+import org.junit.jupiter.api.Test;
+
+public class JspecifyNullSafetyTest {
+
+ @Test
+ void givenKnownUserId_whenFindNickname_thenReturnsOptionalWithValue() {
+ Optional nickname = findNickname("user123");
+
+ assertTrue(nickname.isPresent());
+ assertEquals("CoolUser", nickname.get());
+ }
+
+ @Test
+ void givenUnknownUserId_whenFindNickname_thenReturnsEmptyOptional() {
+ Optional nickname = findNickname("unknownUser");
+
+ assertTrue(nickname.isEmpty());
+ }
+
+ @Test
+ void givenNonNullArgument_whenValidate_thenDoesNotThrowException() {
+ String result = processNickname("CoolUser");
+ assertEquals("Processed: CoolUser", result);
+ }
+
+ @Test
+ void givenNullArgument_whenValidate_thenThrowsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> processNickname(null));
+ }
+
+ @Test
+ void givenUnknownUserId_whenFindNicknameOrNull_thenReturnsNull() {
+ String nickname = findNicknameOrNull("unknownUser");
+ assertTrue(nickname == null);
+ }
+
+ @Test
+ void givenNullableMethodResult_whenWrappedInOptional_thenHandledSafely() {
+ String nickname = findNicknameOrNull("unknownUser");
+ Optional safeNickname = Optional.ofNullable(nickname);
+
+ assertTrue(safeNickname.isEmpty());
+ }
+
+ private Optional findNickname(String userId) {
+ if ("user123".equals(userId)) {
+ return Optional.of("CoolUser");
+ } else {
+ return Optional.empty();
+ }
+ }
+
+ @Nullable
+ private String findNicknameOrNull(String userId) {
+ if ("user123".equals(userId)) {
+ return "CoolUser";
+ } else {
+ return null;
+ }
+ }
+
+ private String processNickname(String nickname) {
+ Objects.requireNonNull(nickname, "Nickname must not be null");
+ return "Processed: " + nickname;
+ }
+}
diff --git a/static-analysis-modules/pom.xml b/static-analysis-modules/pom.xml
index a21e5953b48f..d881a59efc49 100644
--- a/static-analysis-modules/pom.xml
+++ b/static-analysis-modules/pom.xml
@@ -17,6 +17,7 @@
infer
+ jspecify-nullsafety