From 97ae186a10983d2e90cbc9b769a155eeab15bb8a Mon Sep 17 00:00:00 2001 From: Bruno Salmon Date: Thu, 14 Mar 2024 19:07:08 +0000 Subject: [PATCH 1/4] Removed duplicate dependencies before calling Closure --- .../java/com/vertispan/j2cl/build/provided/ClosureTask.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/j2cl-tasks/src/main/java/com/vertispan/j2cl/build/provided/ClosureTask.java b/j2cl-tasks/src/main/java/com/vertispan/j2cl/build/provided/ClosureTask.java index 683fdfb0..871edfc2 100644 --- a/j2cl-tasks/src/main/java/com/vertispan/j2cl/build/provided/ClosureTask.java +++ b/j2cl-tasks/src/main/java/com/vertispan/j2cl/build/provided/ClosureTask.java @@ -163,7 +163,9 @@ public Task resolve(Project project, Config config) { // Bytecode sources will include original input sources // as well as generated input when the jar was built input(p, OutputTypes.BYTECODE) - )); + )) + // Removing any duplicate dependencies that would otherwise trigger unjustified duplicate paths detection in Closure + .distinct(); Stream jsFromJsZips = scope(project.getDependencies(), Dependency.Scope.RUNTIME) .stream() From 1964519054063263988fb61e335650f3b7dfebc5 Mon Sep 17 00:00:00 2001 From: Bruno Salmon Date: Thu, 23 May 2024 18:04:29 +0100 Subject: [PATCH 2/4] Moved distinct() to upper level (project dependencies) --- .../main/java/com/vertispan/j2cl/build/task/TaskFactory.java | 1 + .../java/com/vertispan/j2cl/build/provided/ClosureTask.java | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/build-caching/src/main/java/com/vertispan/j2cl/build/task/TaskFactory.java b/build-caching/src/main/java/com/vertispan/j2cl/build/task/TaskFactory.java index 78316e45..5ac47414 100644 --- a/build-caching/src/main/java/com/vertispan/j2cl/build/task/TaskFactory.java +++ b/build-caching/src/main/java/com/vertispan/j2cl/build/task/TaskFactory.java @@ -67,6 +67,7 @@ protected List scope(Collection dependencies, Dep return dependencies.stream() .filter(d -> ((com.vertispan.j2cl.build.Dependency) d).belongsToScope(scope)) .map(Dependency::getProject) + .distinct() .collect(Collectors.toUnmodifiableList()); } diff --git a/j2cl-tasks/src/main/java/com/vertispan/j2cl/build/provided/ClosureTask.java b/j2cl-tasks/src/main/java/com/vertispan/j2cl/build/provided/ClosureTask.java index 871edfc2..683fdfb0 100644 --- a/j2cl-tasks/src/main/java/com/vertispan/j2cl/build/provided/ClosureTask.java +++ b/j2cl-tasks/src/main/java/com/vertispan/j2cl/build/provided/ClosureTask.java @@ -163,9 +163,7 @@ public Task resolve(Project project, Config config) { // Bytecode sources will include original input sources // as well as generated input when the jar was built input(p, OutputTypes.BYTECODE) - )) - // Removing any duplicate dependencies that would otherwise trigger unjustified duplicate paths detection in Closure - .distinct(); + )); Stream jsFromJsZips = scope(project.getDependencies(), Dependency.Scope.RUNTIME) .stream() From eaec93d6b204c1b9ff32fa5ebd3fd39183d2a12a Mon Sep 17 00:00:00 2001 From: Bruno Salmon Date: Fri, 31 May 2024 11:58:49 +0100 Subject: [PATCH 3/4] Removed distinct() in TaskFactory and added a test in AbstractBuildMojo instead (root cause) --- .../com/vertispan/j2cl/build/Dependency.java | 18 ++++++++++++++++++ .../vertispan/j2cl/build/task/TaskFactory.java | 1 - .../vertispan/j2cl/mojo/AbstractBuildMojo.java | 6 +++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/build-caching/src/main/java/com/vertispan/j2cl/build/Dependency.java b/build-caching/src/main/java/com/vertispan/j2cl/build/Dependency.java index 1eb7d477..05692449 100644 --- a/build-caching/src/main/java/com/vertispan/j2cl/build/Dependency.java +++ b/build-caching/src/main/java/com/vertispan/j2cl/build/Dependency.java @@ -15,6 +15,8 @@ */ package com.vertispan.j2cl.build; +import java.util.Objects; + /** * A dependency is a reference to another project's contents, scoped to indicate whether these are * required to be compiled against, or linked against (and so are required at runtime). The default @@ -59,4 +61,20 @@ public Scope getScope() { public void setScope(Scope scope) { this.scope = scope; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Dependency that = (Dependency) o; + return Objects.equals(project, that.project) && Objects.equals(scope, that.scope); + } + + @Override + public int hashCode() { + int result = Objects.hashCode(project); + result = 31 * result + Objects.hashCode(scope); + return result; + } } diff --git a/build-caching/src/main/java/com/vertispan/j2cl/build/task/TaskFactory.java b/build-caching/src/main/java/com/vertispan/j2cl/build/task/TaskFactory.java index 5ac47414..78316e45 100644 --- a/build-caching/src/main/java/com/vertispan/j2cl/build/task/TaskFactory.java +++ b/build-caching/src/main/java/com/vertispan/j2cl/build/task/TaskFactory.java @@ -67,7 +67,6 @@ protected List scope(Collection dependencies, Dep return dependencies.stream() .filter(d -> ((com.vertispan.j2cl.build.Dependency) d).belongsToScope(scope)) .map(Dependency::getProject) - .distinct() .collect(Collectors.toUnmodifiableList()); } diff --git a/j2cl-maven-plugin/src/main/java/com/vertispan/j2cl/mojo/AbstractBuildMojo.java b/j2cl-maven-plugin/src/main/java/com/vertispan/j2cl/mojo/AbstractBuildMojo.java index 2b6f751b..bca7d922 100644 --- a/j2cl-maven-plugin/src/main/java/com/vertispan/j2cl/mojo/AbstractBuildMojo.java +++ b/j2cl-maven-plugin/src/main/java/com/vertispan/j2cl/mojo/AbstractBuildMojo.java @@ -345,7 +345,11 @@ private Project buildProjectHelper(MavenProject mavenProject, Artifact artifact, Dependency dep = new Dependency(); dep.setProject(child); dep.setScope(translateScope(mavenDependency.getScope())); - dependencies.add(dep); + // Although this new dependency is generally unique, the replacement mechanism may introduce a duplicate + // dependency if several original artifacts are replaced with the same final artifact. + if (!dependencies.contains(dep)) { // ensures we don't introduce a duplicate dependency (important for J2CL) + dependencies.add(dep); + } } project.setDependencies(dependencies); From b9f084fc8e757b18367115f8d87a2380491cfb44 Mon Sep 17 00:00:00 2001 From: Bruno Salmon Date: Mon, 17 Jun 2024 13:55:02 +0100 Subject: [PATCH 4/4] Updated patch to solve scope conflicts --- .../com/vertispan/j2cl/build/Dependency.java | 18 ---------------- .../j2cl/mojo/AbstractBuildMojo.java | 21 ++++++++++++++++--- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/build-caching/src/main/java/com/vertispan/j2cl/build/Dependency.java b/build-caching/src/main/java/com/vertispan/j2cl/build/Dependency.java index 05692449..1eb7d477 100644 --- a/build-caching/src/main/java/com/vertispan/j2cl/build/Dependency.java +++ b/build-caching/src/main/java/com/vertispan/j2cl/build/Dependency.java @@ -15,8 +15,6 @@ */ package com.vertispan.j2cl.build; -import java.util.Objects; - /** * A dependency is a reference to another project's contents, scoped to indicate whether these are * required to be compiled against, or linked against (and so are required at runtime). The default @@ -61,20 +59,4 @@ public Scope getScope() { public void setScope(Scope scope) { this.scope = scope; } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Dependency that = (Dependency) o; - return Objects.equals(project, that.project) && Objects.equals(scope, that.scope); - } - - @Override - public int hashCode() { - int result = Objects.hashCode(project); - result = 31 * result + Objects.hashCode(scope); - return result; - } } diff --git a/j2cl-maven-plugin/src/main/java/com/vertispan/j2cl/mojo/AbstractBuildMojo.java b/j2cl-maven-plugin/src/main/java/com/vertispan/j2cl/mojo/AbstractBuildMojo.java index bca7d922..e4ee068f 100644 --- a/j2cl-maven-plugin/src/main/java/com/vertispan/j2cl/mojo/AbstractBuildMojo.java +++ b/j2cl-maven-plugin/src/main/java/com/vertispan/j2cl/mojo/AbstractBuildMojo.java @@ -347,9 +347,7 @@ private Project buildProjectHelper(MavenProject mavenProject, Artifact artifact, dep.setScope(translateScope(mavenDependency.getScope())); // Although this new dependency is generally unique, the replacement mechanism may introduce a duplicate // dependency if several original artifacts are replaced with the same final artifact. - if (!dependencies.contains(dep)) { // ensures we don't introduce a duplicate dependency (important for J2CL) - dependencies.add(dep); - } + addDependencyResolveDuplicate(dep, dependencies); // ensures we don't introduce duplicates (important for J2CL) } project.setDependencies(dependencies); @@ -376,6 +374,23 @@ private Project buildProjectHelper(MavenProject mavenProject, Artifact artifact, return project; } + private static void addDependencyResolveDuplicate(Dependency newDep, List dependencies) { + // We check if there is already an existing dependency in the list with the same project + for (int i = 0; i < dependencies.size(); i++) { + Dependency existingDep = dependencies.get(i); + if (Objects.equals(newDep.getProject(), existingDep.getProject())) { + // If we found one, we must keep only 1 dependency. The 2 can differ only by the scope, which has only 2 + // possible values here: COMPILE or BOTH. BOTH is the one to keep in case of duplicates. + if (newDep.getScope() == Dependency.Scope.BOTH) { + dependencies.set(i, newDep); + } + return; + } + } + // If we reach this point, it means there was no existing dependency with the same project in the list + dependencies.add(newDep); // So we can add it + } + private MavenProject resolveNonReactorProjectForArtifact(ProjectBuilder projectBuilder, ProjectBuildingRequest request, Artifact mavenDependency) throws ProjectBuildingException { MavenProject p; request.setProject(null);