diff --git a/nostr-java-api/src/main/java/nostr/api/NostrSpringWebSocketClient.java b/nostr-java-api/src/main/java/nostr/api/NostrSpringWebSocketClient.java index a5b7c94b5..f38e0c34f 100644 --- a/nostr-java-api/src/main/java/nostr/api/NostrSpringWebSocketClient.java +++ b/nostr-java-api/src/main/java/nostr/api/NostrSpringWebSocketClient.java @@ -25,18 +25,34 @@ public class NostrSpringWebSocketClient implements NostrIF { @Getter private Identity sender; - private static NostrSpringWebSocketClient INSTANCE; + private static volatile NostrSpringWebSocketClient INSTANCE; public NostrSpringWebSocketClient(String relayName, String relayUri) { setRelays(Map.of(relayName, relayUri)); } public static NostrIF getInstance() { - return (INSTANCE == null) ? new NostrSpringWebSocketClient() : INSTANCE; + if (INSTANCE == null) { + synchronized (NostrSpringWebSocketClient.class) { + if (INSTANCE == null) { + INSTANCE = new NostrSpringWebSocketClient(); + } + } + } + return INSTANCE; } public static NostrIF getInstance(@NonNull Identity sender) { - return (INSTANCE == null) ? new NostrSpringWebSocketClient(sender) : INSTANCE; + if (INSTANCE == null) { + synchronized (NostrSpringWebSocketClient.class) { + if (INSTANCE == null) { + INSTANCE = new NostrSpringWebSocketClient(sender); + } else if (INSTANCE.getSender() == null) { + INSTANCE.sender = sender; // Initialize sender if not already set + } + } + } + return INSTANCE; } public NostrSpringWebSocketClient(@NonNull Identity sender) { diff --git a/nostr-java-api/src/test/java/nostr/api/unit/NostrSpringWebSocketClientTest.java b/nostr-java-api/src/test/java/nostr/api/unit/NostrSpringWebSocketClientTest.java new file mode 100644 index 000000000..a590c2192 --- /dev/null +++ b/nostr-java-api/src/test/java/nostr/api/unit/NostrSpringWebSocketClientTest.java @@ -0,0 +1,36 @@ +package nostr.api.unit; + +import nostr.api.NostrIF; +import nostr.api.NostrSpringWebSocketClient; +import nostr.id.Identity; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Field; + +import static org.junit.jupiter.api.Assertions.assertSame; + +public class NostrSpringWebSocketClientTest { + + @BeforeEach + void resetSingleton() throws Exception { + Field instance = NostrSpringWebSocketClient.class.getDeclaredField("INSTANCE"); + instance.setAccessible(true); + instance.set(null, null); + } + + @Test + void getInstanceShouldReturnSameInstance() { + NostrIF first = NostrSpringWebSocketClient.getInstance(); + NostrIF second = NostrSpringWebSocketClient.getInstance(); + assertSame(first, second, "Multiple calls should return the same instance"); + } + + @Test + void getInstanceWithIdentityShouldReturnSameInstance() { + Identity identity = Identity.generateRandomIdentity(); + NostrIF first = NostrSpringWebSocketClient.getInstance(identity); + NostrIF second = NostrSpringWebSocketClient.getInstance(); + assertSame(first, second, "Calls with and without identity should return the same instance"); + } +}