diff --git a/pkg/languages/java/maven/maven_test.go b/pkg/languages/java/maven/maven_test.go
index 4c51588..0076e2b 100644
--- a/pkg/languages/java/maven/maven_test.go
+++ b/pkg/languages/java/maven/maven_test.go
@@ -1395,6 +1395,39 @@ func TestMaven_Update_DependencyPropertyMissingInPomAndParentErrors(t *testing.T
}
}
+func TestMaven_Update_DependencyWithProjectVersionSkipsGracefully(t *testing.T) {
+ tmpDir := t.TempDir()
+
+ writeFile(t, filepath.Join(tmpDir, "pom.xml"), `
+
+ 4.0.0
+ com.example
+ parent
+ 1.0.0
+ pom
+
+
+ com.example
+ internal-lib
+ ${project.version}
+
+
+`)
+
+ m := &Maven{}
+ cfg := &languages.UpdateConfig{
+ RootDir: tmpDir,
+ ManifestFile: filepath.Join(tmpDir, "pom.xml"),
+ Dependencies: []languages.Dependency{
+ {Name: "com.example:internal-lib", Version: "2.0.0"},
+ },
+ }
+
+ if err := m.Update(context.Background(), cfg); err != nil {
+ t.Fatalf("Maven.Update() error = %v, want nil", err)
+ }
+}
+
func TestMaven_Update_PropertiesSplitBetweenCurrentAndParent(t *testing.T) {
tmpDir := t.TempDir()
parentPom := filepath.Join(tmpDir, "pom.xml")
diff --git a/pkg/languages/java/maven/updater.go b/pkg/languages/java/maven/updater.go
index 4c3ff7b..d312b0d 100644
--- a/pkg/languages/java/maven/updater.go
+++ b/pkg/languages/java/maven/updater.go
@@ -152,6 +152,14 @@ func dependencyPropertyUpdates(ctx context.Context, pomPath string, patches []Pa
continue
}
+ // project.version is a Maven built-in that mirrors the project's own
+ // tag; skip with an informational message instead of failing.
+ if propertyName == "project.version" {
+ clog.InfoContextf(ctx, "Skipping %s:%s: uses ${project.version} which is the project's own version tag, not a configurable property",
+ patch.GroupID, patch.ArtifactID)
+ continue
+ }
+
// Reuse the existing resolver so current-vs-parent ownership stays consistent.
propertyPomPath, err := resolvePropertyPomPath(ctx, pomPath, propertyName)
if err != nil {