Conversation
WalkthroughThis PR upgrades Spring Boot from 3.2.5 to 3.5.0, migrates from deprecated third-party GraphQL libraries to Spring Boot native GraphQL support, removes unnecessary GraphQL resolver classes, adds the Palantir Docker plugin, refreshes dependencies including Apache Commons and Hazelcast, and replaces Spring/Jetbrains nullability annotations with jspecify annotations throughout the codebase. Changes
Possibly related PRs
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/main/java/org/kpmp/cellTypeSummary/ClusterHierarchy.java (1)
59-62:⚠️ Potential issue | 🟡 Minor
@Nullableon primitiveintis semantically incorrect.The
@Nullableannotation ongetClusterId()has no effect because primitive types cannot be null. This was likely inherited from the previous annotation but should be addressed during this migration.Either:
- Remove
@Nullableif the field is guaranteed to have a value (it's part of@Id)- Change the return type to
Integerif null values are expectedGiven that
clusterIdis part of the composite@Id(line 26), it should never be null, so removing the annotation is the correct fix.Suggested fix
- `@Nullable` public int getClusterId() { return clusterId; }
🧹 Nitpick comments (1)
src/main/java/org/kpmp/geneExpressionSummary/singleNucleus/SNRNAGeneExpressionExpressionSummaryValue2025.java (1)
203-216: Pre-existing NPE risk inequals()andhashCode()with nullable fields.While not introduced by this PR, the nullability migration highlights an inconsistency:
getGene()is marked@Nullable(line 94-95), but bothhashCode()andequals()dereference it without null guards. Ifgeneis ever null, these methods will behave unexpectedly (hashCodeconcatenates "null" string,equalsthrows NPE).Consider adding null checks or reconsidering whether
geneshould truly be nullable given its use as part of the composite@Id.Suggested defensive fix
`@Override` public int hashCode() { - return (gene + cluster).hashCode(); + return java.util.Objects.hash(gene, cluster); } `@Override` public boolean equals(Object obj) { if (obj == this) return true; if (!(obj instanceof SNRNAGeneExpressionExpressionSummaryValue2025)) return false; SNRNAGeneExpressionExpressionSummaryValue2025 snrnaGeneExpressionExpressionSummaryValue2025 = (SNRNAGeneExpressionExpressionSummaryValue2025) obj; - return (snrnaGeneExpressionExpressionSummaryValue2025.getGene().equals(this.getGene()) - && snrnaGeneExpressionExpressionSummaryValue2025.getCluster().equals(this.getCluster())); + return java.util.Objects.equals(snrnaGeneExpressionExpressionSummaryValue2025.getGene(), this.getGene()) + && java.util.Objects.equals(snrnaGeneExpressionExpressionSummaryValue2025.getCluster(), this.getCluster()); }
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 9023862b-2093-4b43-996a-bc877995c748
📒 Files selected for processing (12)
build.gradlechangelog.mdsrc/main/java/org/kpmp/QueryController.javasrc/main/java/org/kpmp/cellType/CellTypeHierarchyResolver.javasrc/main/java/org/kpmp/cellType/CellTypeStructureRegionResolver.javasrc/main/java/org/kpmp/cellType/HubmapOnotologyCellTypeRepository.javasrc/main/java/org/kpmp/cellTypeSummary/ClusterHierarchy.javasrc/main/java/org/kpmp/dataSummary/DataSummaryValue.javasrc/main/java/org/kpmp/gene/GeneService.javasrc/main/java/org/kpmp/geneExpressionSummary/singleNucleus/SNRNAGeneExpressionExpressionSummaryValue2025.javasrc/test/java/org/kpmp/QueryControllerTest.javasrc/test/java/org/kpmp/participant/ParticipantService2025Test.java
💤 Files with no reviewable changes (4)
- src/test/java/org/kpmp/participant/ParticipantService2025Test.java
- src/test/java/org/kpmp/QueryControllerTest.java
- src/main/java/org/kpmp/cellType/CellTypeStructureRegionResolver.java
- src/main/java/org/kpmp/cellType/CellTypeHierarchyResolver.java
| implementation 'org.springframework.boot:spring-boot-starter-graphql' | ||
| implementation 'org.springframework.graphql:spring-graphql' |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'Legacy GraphQL servlet property still present:\n'
rg -n 'graphql\.servlet\.exception-handlers-enabled' src/main/resources/application.properties || true
printf '\nPotential Spring GraphQL replacements in the codebase:\n'
rg -n 'DataFetcherExceptionResolver|@GraphQlExceptionHandler|GraphQlExceptionHandler|@ControllerAdvice' src/main/java src/test/java 2>/dev/null || trueRepository: KPMP/pegasus-data
Length of output: 214
Migrate GraphQL exception handling to Spring GraphQL APIs.
The legacy graphql.servlet.exception-handlers-enabled=true property (line 7 of src/main/resources/application.properties) is still enabled but is from graphql-java-kickstart. After swapping to Spring GraphQL, this property is ignored. No equivalent exception handlers using DataFetcherExceptionResolver beans or @GraphQlExceptionHandler exist in the codebase, which means GraphQL error payloads will differ from the previous behavior. Add a DataFetcherExceptionResolver bean or @GraphQlExceptionHandler methods to preserve the intended error shaping, then remove the legacy property.
| implementation 'org.springframework.boot:spring-boot-starter-graphql' | ||
| implementation 'org.springframework.graphql:spring-graphql' | ||
| implementation 'org.springframework.boot:spring-boot-starter-cache' | ||
| implementation 'com.hazelcast:hazelcast-all:4.2.5' | ||
| implementation ("com.hazelcast:hazelcast") | ||
| implementation 'com.graphql-java:graphql-java-extended-scalars:21.0' |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python - <<'PY'
import re
import urllib.request
build = open("build.gradle", encoding="utf-8").read()
m = re.search(r"graphql-java-extended-scalars:([^']+)", build)
print("build.gradle graphql-java-extended-scalars:", m.group(1) if m else "not found")
pom = urllib.request.urlopen(
"https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-dependencies/3.5.0/spring-boot-dependencies-3.5.0.pom"
).read().decode()
m = re.search(r"<graphql-java.version>([^<]+)</graphql-java.version>", pom)
print("spring-boot-dependencies 3.5.0 graphql-java.version:", m.group(1) if m else "not found")
readme = urllib.request.urlopen(
"https://raw.githubusercontent.com/graphql-java/graphql-java-extended-scalars/master/README.md"
).read().decode()
print("\nCompatibility note from graphql-java-extended-scalars README:")
for line in readme.splitlines():
if (
"use 24.0 or above" in line
or "use 22.0 or above" in line
or "use 21.0 for graphql-java 21.x" in line
):
print(line)
PYRepository: KPMP/pegasus-data
Length of output: 2708
🏁 Script executed:
cat build.gradle | head -60Repository: KPMP/pegasus-data
Length of output: 1959
🏁 Script executed:
rg "spring.boot" build.gradle | head -20Repository: KPMP/pegasus-data
Length of output: 575
🌐 Web query:
Spring Boot 3.5 GraphQL Java version baseline
💡 Result:
Spring Boot 3.5.x’s dependency management upgrades GraphQL Java to 23.1 (i.e., Boot 3.5’s managed/baseline GraphQL Java version). [1]
If you mean the Spring for GraphQL generation used by Boot 3.5 (Spring for GraphQL 1.4.x), its documented GraphQL Java baseline is 24.0+. [2]
Sources: [1] Spring Boot 3.5 Release Notes, [2] Spring for GraphQL “Versions” wiki.
🌐 Web query:
graphql-java-extended-scalars 21.0 compatibility requirements graphql-java version
💡 Result:
com.graphql-java:graphql-java-extended-scalars:21.0 is built to run with com.graphql-java:graphql-java:21.0 (declared as its runtime dependency), so GraphQL Java 21.0 is the required/expected compatible version. [1][2]
It also requires Java 11+ (minimum). [2]
Sources:
[1] https://mvnrepository.com/artifact/com.graphql-java/graphql-java-extended-scalars/21.0/dependencies
[2] https://github.com/graphql-java/graphql-java-extended-scalars/releases (v21.0 notes)
Align graphql-java-extended-scalars with the Spring Boot upgrade.
Line 46 pins graphql-java-extended-scalars:21.0, which depends on graphql-java:21.0. However, Spring Boot 3.5 manages graphql-java:23.1, creating a direct dependency conflict. This mismatch will cause runtime classpath failures when Spring Boot forces the newer GraphQL Java version.
| configurations.all { | ||
| resolutionStrategy { | ||
| force 'com.fasterxml.jackson.core:jackson-databind:2.21.0' | ||
| force 'com.fasterxml.jackson.core:jackson-core:2.21.0' | ||
| force 'com.fasterxml.jackson.core:jackson-annotations:2.21.0' | ||
| } | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python - <<'PY'
import urllib.request
import xml.etree.ElementTree as ET
print("Forced Jackson lines in build.gradle:")
for i, line in enumerate(open("build.gradle", encoding="utf-8"), 1):
if 55 <= i <= 61:
print(f"{i}: {line.rstrip()}")
pom = urllib.request.urlopen(
"https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-starter-json/3.5.0/spring-boot-starter-json-3.5.0.pom"
).read()
root = ET.fromstring(pom)
ns = {"m": "http://maven.apache.org/POM/4.0.0"}
wanted = {
"jackson-databind",
"jackson-datatype-jdk8",
"jackson-datatype-jsr310",
"jackson-module-parameter-names",
}
print("\nSpring Boot 3.5.0 starter-json declares:")
for dep in root.findall(".//m:dependency", ns):
aid = dep.findtext("m:artifactId", default="", namespaces=ns)
ver = dep.findtext("m:version", default="", namespaces=ns)
if aid in wanted:
print(f"{aid}: {ver}")
PYRepository: KPMP/pegasus-data
Length of output: 2979
🏁 Script executed:
cat build.gradleRepository: KPMP/pegasus-data
Length of output: 2961
🏁 Script executed:
rg "spring-boot" build.gradle -A 2 -B 2Repository: KPMP/pegasus-data
Length of output: 1159
🌐 Web query:
Spring Boot 3.5.0 spring-boot-starter-json Jackson version dependencies
💡 Result:
For Spring Boot 3.5.0, spring-boot-starter-json brings in (compile scope) these Jackson artifacts, all at version 2.19.0: jackson-databind, jackson-datatype-jdk8, jackson-datatype-jsr310, jackson-module-parameter-names (plus spring-web). [1]
Spring Boot 3.5.0’s dependency management (the spring-boot-dependencies BOM) sets jackson-bom.version to 2.19.0, so any other Jackson modules you add without an explicit version will also be managed to 2.19.0. [2]
Sources: [1] [2]
Remove the partial Jackson version override that splits Jackson across minor versions.
Spring Boot 3.5.0's JSON starter brings jackson-databind, jackson-datatype-jdk8, jackson-datatype-jsr310, and jackson-module-parameter-names at version 2.19.0. The forced overrides on lines 57–59 only target three modules (jackson-databind, jackson-core, jackson-annotations) at 2.21.0, leaving the other Jackson modules at 2.19.0. This creates a mixed 2.19/2.21 dependency graph on the classpath. Use the Jackson BOM or upgrade to a Spring Boot release that defaults to 2.21+ instead.
One way to align the whole Jackson family
-configurations.all {
- resolutionStrategy {
- force 'com.fasterxml.jackson.core:jackson-databind:2.21.0'
- force 'com.fasterxml.jackson.core:jackson-core:2.21.0'
- force 'com.fasterxml.jackson.core:jackson-annotations:2.21.0'
- }
-}
+dependencyManagement {
+ imports {
+ mavenBom "com.fasterxml.jackson:jackson-bom:2.21.0"
+ }
+}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| configurations.all { | |
| resolutionStrategy { | |
| force 'com.fasterxml.jackson.core:jackson-databind:2.21.0' | |
| force 'com.fasterxml.jackson.core:jackson-core:2.21.0' | |
| force 'com.fasterxml.jackson.core:jackson-annotations:2.21.0' | |
| } | |
| } | |
| dependencyManagement { | |
| imports { | |
| mavenBom "com.fasterxml.jackson:jackson-bom:2.21.0" | |
| } | |
| } |
| Brief summary: | ||
| - Fix vulnerabilities found in docker image |
There was a problem hiding this comment.
Use past tense for consistency with other changelog entries.
The changelog entry uses "Fix" (present/imperative tense) while other recent releases use past tense (e.g., "Fixed issue" in Release 3.1, "fixed duplicate data" in Release 3.2). Additionally, the description is vague. Given the PR context shows Spring Boot upgrade from 3.2.5 to 3.5.0 and dependency updates, consider being more specific.
📝 Suggested improvement for consistency and clarity
Brief summary:
-- Fix vulnerabilities found in docker image
+- Fixed vulnerabilities in docker image by upgrading Spring Boot to 3.5.0 and updating dependencies📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Brief summary: | |
| - Fix vulnerabilities found in docker image | |
| Brief summary: | |
| - Fixed vulnerabilities in docker image by upgrading Spring Boot to 3.5.0 and updating dependencies |
Summary by CodeRabbit
Release Notes
Bug Fixes
Chores