From df880acbf9555207ce1a321a5585bd4c32270e6e Mon Sep 17 00:00:00 2001 From: erict875 Date: Sun, 5 Oct 2025 17:07:52 +0100 Subject: [PATCH 1/6] wip: migrate nostr-java to nostr-java-bom - needs BOM update for Spring Boot --- PR.md | 82 ++++++++++++ nostr-java-api/pom.xml | 24 ++-- nostr-java-base/pom.xml | 10 +- nostr-java-client/pom.xml | 12 +- nostr-java-crypto/pom.xml | 6 +- nostr-java-encryption/pom.xml | 8 +- nostr-java-event/pom.xml | 12 +- .../event/unit/CalendarContentAddTagTest.java | 66 ++++++++++ nostr-java-examples/pom.xml | 2 +- nostr-java-id/pom.xml | 6 +- nostr-java-util/pom.xml | 6 +- pom.xml | 121 +++--------------- 12 files changed, 207 insertions(+), 148 deletions(-) create mode 100644 PR.md create mode 100644 nostr-java-event/src/test/java/nostr/event/unit/CalendarContentAddTagTest.java diff --git a/PR.md b/PR.md new file mode 100644 index 00000000..4067dc90 --- /dev/null +++ b/PR.md @@ -0,0 +1,82 @@ +Proposed title: fix: Fix CalendarContent addTag duplication; address Qodana findings and add tests + +## Summary +This PR fixes a duplication bug in `CalendarContent.addTag`, cleans up Qodana-reported issues (dangling Javadoc, missing Javadoc descriptions, fields that can be final, and safe resource usage), and adds unit tests to validate correct tag handling. + +Related issue: #____ + +## What changed? +- Fix duplication in calendar tag collection + - F:nostr-java-event/src/main/java/nostr/event/entities/CalendarContent.java†L184-L188 + - Replace re-put/addAll pattern with `computeIfAbsent(...).add(...)` to append a single element without duplicating the list. + - F:nostr-java-event/src/main/java/nostr/event/entities/CalendarContent.java†L40-L40 + - Make `classTypeTagsMap` final. + +- Unit tests for calendar tag handling + - F:nostr-java-event/src/test/java/nostr/event/unit/CalendarContentAddTagTest.java†L16-L31 + - F:nostr-java-event/src/test/java/nostr/event/unit/CalendarContentAddTagTest.java†L33-L45 + - F:nostr-java-event/src/test/java/nostr/event/unit/CalendarContentAddTagTest.java†L47-L64 + +- Javadoc placement fixes (resolve DanglingJavadoc by placing Javadoc above `@Override`) + - F:nostr-java-api/src/main/java/nostr/api/NostrSpringWebSocketClient.java†L112-L116, L132-L136, L146-L150, L155-L159, L164-L168, L176-L180, L206-L210, L293-L297, L302-L306, L321-L325 + - F:nostr-java-event/src/main/java/nostr/event/json/codec/GenericEventDecoder.java†L25-L33 + - F:nostr-java-event/src/main/java/nostr/event/json/codec/Nip05ContentDecoder.java†L22-L30 + - F:nostr-java-event/src/main/java/nostr/event/json/codec/BaseTagDecoder.java†L22-L30 + - F:nostr-java-event/src/main/java/nostr/event/json/codec/BaseMessageDecoder.java†L27-L35 + - F:nostr-java-event/src/main/java/nostr/event/json/codec/GenericTagDecoder.java†L26-L34 + +- Javadoc description additions (fix `@param`, `@return`, `@throws` missing) + - F:nostr-java-crypto/src/main/java/nostr/crypto/schnorr/Schnorr.java†L20-L28, L33-L41 + - F:nostr-java-crypto/src/main/java/nostr/crypto/bech32/Bech32.java†L80-L89, L91-L100, L120-L128 + +- Fields that may be final + - F:nostr-java-api/src/main/java/nostr/api/WebSocketClientHandler.java†L31-L32 + - F:nostr-java-event/src/main/java/nostr/event/entities/CalendarContent.java†L40-L40 + +- Resource inspections: explicitly managed or non-closeable resources + - F:nostr-java-api/src/main/java/nostr/api/WebSocketClientHandler.java†L87-L90, L101-L103 + - Suppress false positives for long-lived `SpringWebSocketClient` managed by handler lifecycle. + - F:nostr-java-util/src/main/java/nostr/util/validator/Nip05Validator.java†L95-L96 + - Suppress on JDK `HttpClient` which is not AutoCloseable and intended to be reused. + +- Remove redundant catch and commented-out code + - F:nostr-java-event/src/main/java/nostr/event/impl/CreateOrUpdateProductEvent.java†L59-L61 + - F:nostr-java-event/src/main/java/nostr/event/entities/ZapRequest.java†L12-L19 + +## BREAKING +None. + +## Review focus +- Confirm the intention for `CalendarContent` is to accumulate tags per code without list duplication. +- Sanity-check placement of `@SuppressWarnings("resource")` where resources are explicitly lifecycle-managed. + +## Checklist +- [x] Scope ≤ 300 lines (or split/stack) +- [x] Title is verb + object (Conventional Commits: `fix: ...`) +- [x] Description links the issue and answers “why now?” +- [x] BREAKING flagged if needed +- [x] Tests/docs updated (if relevant) + +## Testing +- ✅ `mvn -q -DskipTests package` + - Build succeeded for all modules. +- ✅ `mvn -q -Dtest=CalendarContentAddTagTest test` (run in `nostr-java-event`) + - Tests executed successfully. New tests validate: + - Two hashtags produce exactly two items without duplication. + - Single participant `PubKeyTag` stored once with expected key. + - Different tag types tracked independently. +- ⚠️ `mvn -q verify` + - Fails in this sandbox due to Mockito’s inline mock-maker requiring a Byte Buddy agent attach, which is blocked: + - Excerpt: + - `Could not initialize plugin: interface org.mockito.plugins.MockMaker` + - `MockitoInitializationException: Could not initialize inline Byte Buddy mock maker.` + - `Could not self-attach to current VM using external process` + - Local runs in a non-restricted environment should pass once the agent is allowed or Mockito is configured accordingly. + +## Network Access +- No external network calls required by these changes. +- No blocked domains observed. Test failures are unrelated to network and stem from sandbox agent-attach restrictions. + +## Notes +- `CalendarContent.addTag` previously reinserted the list and added all elements again, causing duplication. The fix uses `computeIfAbsent` and appends exactly one element. +- I intentionally placed `@SuppressWarnings("resource")` where objects are long-lived or non-`AutoCloseable` (e.g., Java `HttpClient`) to silence false positives noted by Qodana. diff --git a/nostr-java-api/pom.xml b/nostr-java-api/pom.xml index cfe84bd5..e04ea408 100644 --- a/nostr-java-api/pom.xml +++ b/nostr-java-api/pom.xml @@ -26,42 +26,42 @@ org.apache.commons commons-text - ${commons-text.version} + ${project.groupId} nostr-java-client - ${nostr-java.version} + ${project.groupId} nostr-java-encryption - ${nostr-java.version} + ${project.groupId} nostr-java-id - ${nostr-java.version} + ${project.groupId} nostr-java-event - ${nostr-java.version} + ${project.groupId} nostr-java-util - ${nostr-java.version} + ${project.groupId} nostr-java-crypto - ${nostr-java.version} + org.springframework.boot spring-boot-starter - ${spring-boot.version} + com.fasterxml.jackson.core @@ -70,7 +70,7 @@ org.projectlombok lombok - ${lombok.version} + provided @@ -85,19 +85,19 @@ org.springframework.boot spring-boot-starter-test - ${spring-boot.version} + test com.google.guava guava - ${guava.version} + test org.junit.jupiter junit-jupiter - ${junit-jupiter.version} + test diff --git a/nostr-java-base/pom.xml b/nostr-java-base/pom.xml index 2fdbd817..aacc9e85 100644 --- a/nostr-java-base/pom.xml +++ b/nostr-java-base/pom.xml @@ -27,12 +27,12 @@ ${project.groupId} nostr-java-util - ${nostr-java.version} + ${project.groupId} nostr-java-crypto - ${nostr-java.version} + @@ -43,14 +43,14 @@ com.fasterxml.jackson.module jackson-module-blackbird - ${jackson-module-blackbird.version} + org.projectlombok lombok - ${lombok.version} + provided @@ -62,7 +62,7 @@ org.junit.jupiter junit-jupiter - ${junit-jupiter.version} + test diff --git a/nostr-java-client/pom.xml b/nostr-java-client/pom.xml index 4f560fb6..1a2e05ea 100644 --- a/nostr-java-client/pom.xml +++ b/nostr-java-client/pom.xml @@ -27,14 +27,14 @@ ${project.groupId} nostr-java-id - ${nostr-java.version} + org.springframework.boot spring-boot-starter-websocket - ${spring-boot.version} + org.springframework @@ -53,14 +53,14 @@ org.awaitility awaitility - ${awaitility.version} + org.projectlombok lombok - ${lombok.version} + provided @@ -68,13 +68,13 @@ org.junit.jupiter junit-jupiter - ${junit-jupiter.version} + test org.springframework.boot spring-boot-starter-test - ${spring-boot.version} + test diff --git a/nostr-java-crypto/pom.xml b/nostr-java-crypto/pom.xml index 47d9aa38..daca07cc 100644 --- a/nostr-java-crypto/pom.xml +++ b/nostr-java-crypto/pom.xml @@ -42,14 +42,14 @@ ${project.groupId} nostr-java-util - ${nostr-java.version} + org.projectlombok lombok - ${lombok.version} + provided @@ -61,7 +61,7 @@ org.junit.jupiter junit-jupiter - ${junit-jupiter.version} + test diff --git a/nostr-java-encryption/pom.xml b/nostr-java-encryption/pom.xml index 1bce75e5..406424b2 100644 --- a/nostr-java-encryption/pom.xml +++ b/nostr-java-encryption/pom.xml @@ -30,19 +30,19 @@ ${project.groupId} nostr-java-crypto - ${nostr-java.version} + ${project.groupId} nostr-java-util - ${nostr-java.version} + org.projectlombok lombok - ${lombok.version} + provided @@ -50,7 +50,7 @@ org.junit.jupiter junit-jupiter - ${junit-jupiter.version} + test diff --git a/nostr-java-event/pom.xml b/nostr-java-event/pom.xml index 5fea85e6..871cbb5d 100644 --- a/nostr-java-event/pom.xml +++ b/nostr-java-event/pom.xml @@ -27,17 +27,17 @@ ${project.groupId} nostr-java-base - ${nostr-java.version} + ${project.groupId} nostr-java-crypto - ${nostr-java.version} + ${project.groupId} nostr-java-util - ${nostr-java.version} + com.fasterxml.jackson.core @@ -46,12 +46,12 @@ com.fasterxml.jackson.module jackson-module-blackbird - ${jackson-module-blackbird.version} + org.projectlombok lombok - ${lombok.version} + provided @@ -61,7 +61,7 @@ org.junit.jupiter junit-jupiter - ${junit-jupiter.version} + test diff --git a/nostr-java-event/src/test/java/nostr/event/unit/CalendarContentAddTagTest.java b/nostr-java-event/src/test/java/nostr/event/unit/CalendarContentAddTagTest.java new file mode 100644 index 00000000..5ea56485 --- /dev/null +++ b/nostr-java-event/src/test/java/nostr/event/unit/CalendarContentAddTagTest.java @@ -0,0 +1,66 @@ +package nostr.event.unit; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import org.junit.jupiter.api.Test; +import nostr.base.PublicKey; +import nostr.event.entities.CalendarContent; +import nostr.event.tag.HashtagTag; +import nostr.event.tag.IdentifierTag; +import nostr.event.tag.PubKeyTag; + +public class CalendarContentAddTagTest { + + @Test + // Ensures adding two hashtag tags results in exactly two items without duplication. + void testAddTwoHashtagTagsNoDuplication() { + CalendarContent content = new CalendarContent<>(new IdentifierTag("id-1"), "title", 1L); + + HashtagTag t1 = new HashtagTag("tag1"); + HashtagTag t2 = new HashtagTag("tag2"); + + content.addHashtagTag(t1); + content.addHashtagTag(t2); + + List tags = content.getHashtagTags(); + assertEquals(2, tags.size()); + assertEquals("tag1", tags.get(0).getHashTag()); + assertEquals("tag2", tags.get(1).getHashTag()); + } + + @Test + // Verifies adding a participant PubKeyTag produces a single entry with the expected key. + void testAddParticipantPubKeyTagNoDuplication() { + CalendarContent content = new CalendarContent<>(new IdentifierTag("id-2"), "title", 1L); + + String hex = "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"; + PubKeyTag p = new PubKeyTag(new PublicKey(hex)); + content.addParticipantPubKeyTag(p); + + List pTags = content.getParticipantPubKeyTags(); + assertEquals(1, pTags.size()); + assertEquals(hex, pTags.get(0).getPublicKey().toString()); + } + + @Test + // Confirms different tag types are tracked independently with correct counts. + void testAddMultipleTagTypesIndependent() { + CalendarContent content = new CalendarContent<>(new IdentifierTag("id-3"), "title", 1L); + + // Add two hashtags + content.addHashtagTag(new HashtagTag("a")); + content.addHashtagTag(new HashtagTag("b")); + + // Add one participant pubkey + content.addParticipantPubKeyTag( + new PubKeyTag( + new PublicKey("2bed79f81439ff794cf5ac5f7bff9121e257f399829e472c7a14d3e86fe76984"))); + + assertEquals(2, content.getHashtagTags().size()); + assertEquals(1, content.getParticipantPubKeyTags().size()); + assertTrue(content.getGeohashTag().isEmpty()); + } +} + diff --git a/nostr-java-examples/pom.xml b/nostr-java-examples/pom.xml index 3c6fef75..66701cad 100644 --- a/nostr-java-examples/pom.xml +++ b/nostr-java-examples/pom.xml @@ -27,7 +27,7 @@ ${project.groupId} nostr-java-api - ${nostr-java.version} + diff --git a/nostr-java-id/pom.xml b/nostr-java-id/pom.xml index e0207bc1..33b5e351 100644 --- a/nostr-java-id/pom.xml +++ b/nostr-java-id/pom.xml @@ -27,12 +27,12 @@ ${project.groupId} nostr-java-event - ${nostr-java.version} + org.projectlombok lombok - ${lombok.version} + provided @@ -42,7 +42,7 @@ org.junit.jupiter junit-jupiter - ${junit-jupiter.version} + test diff --git a/nostr-java-util/pom.xml b/nostr-java-util/pom.xml index 6683b65b..82fe743f 100644 --- a/nostr-java-util/pom.xml +++ b/nostr-java-util/pom.xml @@ -35,12 +35,12 @@ com.fasterxml.jackson.module jackson-module-blackbird - ${jackson-module-blackbird.version} + org.projectlombok lombok - ${lombok.version} + provided @@ -50,7 +50,7 @@ org.junit.jupiter junit-jupiter - ${junit-jupiter.version} + test diff --git a/pom.xml b/pom.xml index 633a3542..a35fd2c6 100644 --- a/pom.xml +++ b/pom.xml @@ -6,12 +6,6 @@ 0.4.0 pom - - org.springframework.boot - spring-boot-starter-parent - 3.5.5 - - ${project.artifactId} Java SDK for Nostr, for generating, signing and publishing events to relays https://github.com/tcheeric/nostr-java @@ -74,51 +68,39 @@ - 0.4.0 21 - - 3.5.5 ${java.version} ${java.version} UTF-8 - - 1.81 - 4.3.0 - 1.81 - 3.18.0 - 1.12.0 - 2.19.2 - 1.18.38 - - - 33.4.8-jre - 5.13.4 - 1.21.3 - - - 0.8.0 - 0.8.13 - 1.7.2 - 3.14.0 - 3.5.3 - 3.2.8 - 3.11.3 - 3.3.1 - 3.5.3 + + 1.0.0 + + + + + xyz.tcheeric + nostr-java-bom + ${nostr-java-bom.version} + pom + import + + + + + org.sonatype.central central-publishing-maven-plugin - ${central-publishing-maven-plugin.version} true central @@ -129,33 +111,14 @@ org.apache.maven.plugins maven-source-plugin - ${maven-source-plugin.version} - - - attach-sources - - jar-no-fork - - - org.apache.maven.plugins maven-javadoc-plugin - ${maven-javadoc-plugin.version} - - - attach-javadocs - - jar - - - org.apache.maven.plugins maven-gpg-plugin - ${maven-gpg-plugin.version} sign-artifacts @@ -175,72 +138,22 @@ org.codehaus.mojo flatten-maven-plugin - ${flatten-maven-plugin.version} - - true - resolveCiFriendliesOnly - - - - flatten - process-resources - - flatten - - - - flatten.clean - clean - - clean - - - org.apache.maven.plugins maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${maven.compiler.source} - ${maven.compiler.target} - org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} - - - - test - - - org.jacoco jacoco-maven-plugin - ${jacoco-maven-plugin.version} - - - - prepare-agent - - - - report - verify - - report - - - org.apache.maven.plugins maven-failsafe-plugin - ${maven-failsafe-plugin.version} @@ -263,11 +176,9 @@ maven-surefire-plugin - ${maven-surefire-plugin.version} maven-failsafe-plugin - ${maven-failsafe-plugin.version} org.apache.maven.plugins From 2d213802ac9b854d0150624ad8d4b5eb0dfbb098 Mon Sep 17 00:00:00 2001 From: erict875 Date: Sun, 5 Oct 2025 17:30:03 +0100 Subject: [PATCH 2/6] feat: migrate nostr-java to nostr-java-bom and bump to 0.5.0 --- nostr-java-api/pom.xml | 2 +- nostr-java-base/pom.xml | 2 +- nostr-java-client/pom.xml | 4 ++-- nostr-java-crypto/pom.xml | 3 +-- nostr-java-encryption/pom.xml | 2 +- nostr-java-event/pom.xml | 2 +- nostr-java-examples/pom.xml | 2 +- nostr-java-id/pom.xml | 2 +- nostr-java-util/pom.xml | 3 +-- pom.xml | 4 ++-- 10 files changed, 12 insertions(+), 14 deletions(-) diff --git a/nostr-java-api/pom.xml b/nostr-java-api/pom.xml index e04ea408..c44977af 100644 --- a/nostr-java-api/pom.xml +++ b/nostr-java-api/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.4.0 + 0.5.0 ../pom.xml diff --git a/nostr-java-base/pom.xml b/nostr-java-base/pom.xml index aacc9e85..d7e6c60f 100644 --- a/nostr-java-base/pom.xml +++ b/nostr-java-base/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.4.0 + 0.5.0 ../pom.xml diff --git a/nostr-java-client/pom.xml b/nostr-java-client/pom.xml index 1a2e05ea..e0167f83 100644 --- a/nostr-java-client/pom.xml +++ b/nostr-java-client/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.4.0 + 0.5.0 ../pom.xml @@ -53,7 +53,7 @@ org.awaitility awaitility - + compile diff --git a/nostr-java-crypto/pom.xml b/nostr-java-crypto/pom.xml index daca07cc..61047321 100644 --- a/nostr-java-crypto/pom.xml +++ b/nostr-java-crypto/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.4.0 + 0.5.0 ../pom.xml @@ -35,7 +35,6 @@ org.bouncycastle bcprov-jdk18on - ${bcprov-jdk18on.version} diff --git a/nostr-java-encryption/pom.xml b/nostr-java-encryption/pom.xml index 406424b2..2b879496 100644 --- a/nostr-java-encryption/pom.xml +++ b/nostr-java-encryption/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.4.0 + 0.5.0 ../pom.xml diff --git a/nostr-java-event/pom.xml b/nostr-java-event/pom.xml index 871cbb5d..0c5346b5 100644 --- a/nostr-java-event/pom.xml +++ b/nostr-java-event/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.4.0 + 0.5.0 ../pom.xml diff --git a/nostr-java-examples/pom.xml b/nostr-java-examples/pom.xml index 66701cad..635a3f6c 100644 --- a/nostr-java-examples/pom.xml +++ b/nostr-java-examples/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.4.0 + 0.5.0 ../pom.xml diff --git a/nostr-java-id/pom.xml b/nostr-java-id/pom.xml index 33b5e351..f0075b4c 100644 --- a/nostr-java-id/pom.xml +++ b/nostr-java-id/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.4.0 + 0.5.0 ../pom.xml diff --git a/nostr-java-util/pom.xml b/nostr-java-util/pom.xml index 82fe743f..470f26e6 100644 --- a/nostr-java-util/pom.xml +++ b/nostr-java-util/pom.xml @@ -4,7 +4,7 @@ xyz.tcheeric nostr-java - 0.4.0 + 0.5.0 ../pom.xml @@ -26,7 +26,6 @@ org.apache.commons commons-lang3 - ${commons-lang3.version} com.fasterxml.jackson.core diff --git a/pom.xml b/pom.xml index a35fd2c6..9dad0b19 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ xyz.tcheeric nostr-java - 0.4.0 + 0.5.0 pom ${project.artifactId} @@ -74,7 +74,7 @@ UTF-8 - 1.0.0 + 1.1.0 1.1.0 + + + 0.8.0 + 3.3.1 + 3.11.3 + 3.2.8 + 1.7.2 + 3.14.0 + 3.5.3 + 0.8.13 + 3.5.3 org.sonatype.central central-publishing-maven-plugin + ${central.publishing.plugin.version} true central @@ -111,14 +122,33 @@ org.apache.maven.plugins maven-source-plugin + ${maven.source.plugin.version} + + + attach-sources + + jar-no-fork + + + org.apache.maven.plugins maven-javadoc-plugin + ${maven.javadoc.plugin.version} + + + attach-javadocs + + jar + + + org.apache.maven.plugins maven-gpg-plugin + ${maven.gpg.plugin.version} sign-artifacts @@ -138,22 +168,72 @@ org.codehaus.mojo flatten-maven-plugin + ${flatten.plugin.version} + + true + resolveCiFriendliesOnly + + + + flatten + process-resources + + flatten + + + + flatten.clean + clean + + clean + + + org.apache.maven.plugins maven-compiler-plugin + ${maven.compiler.plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + org.apache.maven.plugins maven-surefire-plugin + ${maven.surefire.plugin.version} + + + + test + + + org.jacoco jacoco-maven-plugin + ${jacoco.plugin.version} + + + + prepare-agent + + + + report + verify + + report + + + org.apache.maven.plugins maven-failsafe-plugin + ${maven.failsafe.plugin.version} @@ -176,9 +256,11 @@ maven-surefire-plugin + ${maven.surefire.plugin.version} maven-failsafe-plugin + ${maven.failsafe.plugin.version} org.apache.maven.plugins