Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deduplicate replaced dependencies #259

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

salmonb
Copy link
Contributor

@salmonb salmonb commented Mar 14, 2024

No description provided.

));
))
// Removing any duplicate dependencies that would otherwise trigger unjustified duplicate paths detection in Closure
.distinct();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like doing this, for two chief reasons:

  • Since it seems like there could be more than one that might be the "right" answer expected by different libraries on a classpath. The BUNDLE_JAR tasks have a certain order (both of files in a maven module, and maven modules in the tree) already so that a distinct() will probably do the opposite of what you intended, but module and file order here is not specified at all, is likely to be maven- and/or filesystem-specific.
  • It is currently convenient that modules are mostly 1:1 with paths, but that is mostly happenstance, and not something to rely on.

Questions to consider:

  • Closure module de-duping has nothing to do with the module name - path similarity doesn't bother closure, only module names, so in the long run this isn't even fixing the right thing...?
  • This isn't necessarily ordered though right? How are you certain that this removes the "right" files?
  • Also, I'm pretty sure you also need this in the BUNDLE_JAR wiring so that j2cl:watch still works and doesnt break at runtime (which is how it responds to duplicate modules).

I think it probably should be redone in your own fork or your own task (note that taskfactory instances are picked up via service loader, so this is well supported...) as "this is a specific fix needed for my own build", or redone in this patch as "this dedup's goog.provides (by name), goog.modules (by name), and es6 modules (by path), not dedup all files by path".

@salmonb
Copy link
Contributor Author

salmonb commented May 23, 2024

The issue I'm facing is that after the dependency replacements have been applied, the effective project has some final dependencies listed multiple times.

The Vertispan plugin doesn't manage this case properly. In general in Maven it's allowed to have the same dependency listed multiple times in a pom.xml, even if it's not recommended, it's not a fault and this shouldn't break the build. And in particular if that pom is an effective pom generated by a tool (even if that effective pom is just virtual in memory) it should be even more relevant to not break the build.

I moved the distinct() operator to an upper level, in the TaskFactory.scope() method, and this solves this issue in a cleaner way than my initial proposition. Indeed, in which case would it make sense to have duplicates in the list of Project returned by this method?

Can you please reconsider my PR?

@niloc132
Copy link
Member

In general in Maven it's allowed

You're conflating Maven and java - in Maven with the j2cl-maven-plugin this is allowed too, and while Java handles duplicates on its classpath very gracefully, ClosureCompiler does not.

You're also mixing "dependency" and "class" - listing a single dependency, even with different versions, multiple times is managed the way you would expect with Maven for a Java project too - Maven will decide which version of that groupId+artifactId to use (default strategy is to pick the definition "closest" to your project, which is sort of defined as "sort the various dependency decls by distance from the project being built, and use the first"), and will not include the others. You can see this when reviewing mvn dependency:tree -Dverbose and looking for duplicates and conflicts). But the issue you're encountering here isn't around the dependency being listed twice, but two distinct dependencies (groupId+artifactId+classifier) containing the same resource. Maven doesn't care about this, only thinks about dependencies, and Java just picks the "first" one it encounters on the classpath. J2CL and Javac/turbine also don't care, they don't mind duplicates, they just pick the first. But it is explicitly an error in closure to have duplicate declarations of closure modules or provides.


With all of that said, if this fix resolves your bug, it sounds like you have two classifiers but the same groupid+artifactid for some dependency, and, most importantly, that these artifacts contain the same .java (or potentially .js) files.

If that is the case, it probably is correct for your project to just use <excludes> to keep one off the final classpath, so that closure only sees one set of them (and so you don't transpile them twice, and muddy up the classpath for anything else that depends on them).

And if so, this could break cases where "classifier" is used to mean "this artifact is different from that one for some important reason" - imagine a library that ships with an optional shim, and you can add the classifier to opt-in to using the shim. Not saying someone is necessarily using it this way, but it is possible at least, and it would break that case (without a clear rule about "the first one wins" or how to define which classifier beats other classifiers).

But this fix will not solve the "bug" where two distinctly named dependencies contain the same class or js file, which seemed closer to what the original fix was intended to do (and would have solved). Can we take a few steps back and look at the problem rather than jumping to solutions? If an excludes (or possibly even "just don't add that extra classifier=sources dep") resolves this, it would seem simpler...

@salmonb
Copy link
Contributor Author

salmonb commented May 24, 2024

Ok, let's try to investigate further the cause, but I don't think I have 2 classifiers of the same groupid+artifactid like you said, because there are no classifiers other than :jar - see my mvn dependency:tree -Dverbose below:

[INFO] Scanning for projects...
[INFO] 
[INFO] ----------< dev.webfx:webfx-demo-jarkanoid-application-j2cl >-----------
[INFO] Building webfx-demo-jarkanoid-application-j2cl 0.1.0-SNAPSHOT
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ webfx-demo-jarkanoid-application-j2cl ---
[INFO] dev.webfx:webfx-demo-jarkanoid-application-j2cl:jar:0.1.0-SNAPSHOT
[INFO] +- org.treblereel.j2cl.processors:annotations:jar:0.6.4:compile
[INFO] |  \- org.treblereel.j2cl.processors:common:jar:0.6.4:compile
[INFO] |     \- (com.google.elemental2:elemental2-dom:jar:1.2.1:compile - version managed from 1.1.0; omitted for duplicate)
[INFO] +- org.treblereel.j2cl.processors:processors:jar:0.6.4:provided
[INFO] +- dev.webfx:webfx-demo-jarkanoid-application:jar:0.1.0-SNAPSHOT:compile
[INFO] |  +- dev.webfx:webfx-kit-util-scene:jar:0.1.0-SNAPSHOT:compile
[INFO] |  |  +- dev.webfx:webfx-kit-launcher:jar:0.1.0-SNAPSHOT:compile
[INFO] |  |  |  +- (dev.webfx:webfx-platform-boot:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  |  +- (dev.webfx:webfx-platform-console:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  |  +- (dev.webfx:webfx-platform-service:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  |  +- (dev.webfx:webfx-platform-uischeduler:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  |  \- (dev.webfx:webfx-platform-util:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  \- (dev.webfx:webfx-platform-os:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  +- dev.webfx:webfx-platform-resource:jar:0.1.0-SNAPSHOT:compile
[INFO] |  |  \- (dev.webfx:webfx-platform-service:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  +- dev.webfx:webfx-platform-scheduler:jar:0.1.0-SNAPSHOT:compile
[INFO] |  |  +- (dev.webfx:webfx-platform-console:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  +- (dev.webfx:webfx-platform-service:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  \- (dev.webfx:webfx-platform-util:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  +- dev.webfx:webfx-platform-shutdown:jar:0.1.0-SNAPSHOT:compile
[INFO] |  |  \- (dev.webfx:webfx-platform-service:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  +- dev.webfx:webfx-platform-storage:jar:0.1.0-SNAPSHOT:compile
[INFO] |  |  \- (dev.webfx:webfx-platform-service:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  +- dev.webfx:webfx-platform-useragent:jar:0.1.0-SNAPSHOT:compile
[INFO] |  |  \- (dev.webfx:webfx-platform-service:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  \- dev.webfx:webfx-platform-windowlocation:jar:0.1.0-SNAPSHOT:compile
[INFO] |     +- (dev.webfx:webfx-platform-service:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |     \- (dev.webfx:webfx-platform-util:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] +- dev.webfx:webfx-kit-javafxmedia-peers-gwt-j2cl:jar:0.1.0-SNAPSHOT:compile
[INFO] |  +- dev.webfx:webfx-kit-javafxbase-emul:jar:0.1.0-SNAPSHOT:compile
[INFO] |  +- dev.webfx:webfx-kit-javafxgraphics-emul:jar:0.1.0-SNAPSHOT:compile
[INFO] |  |  +- (dev.webfx:webfx-kit-javafxbase-emul:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  +- (dev.webfx:webfx-kit-javafxgraphics-peers:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  +- (dev.webfx:webfx-kit-launcher:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  +- dev.webfx:webfx-kit-util:jar:0.1.0-SNAPSHOT:compile
[INFO] |  |  |  \- (dev.webfx:webfx-platform-util:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  +- (dev.webfx:webfx-platform-console:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  +- (dev.webfx:webfx-platform-scheduler:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  +- (dev.webfx:webfx-platform-service:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  +- (dev.webfx:webfx-platform-shutdown:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  +- (dev.webfx:webfx-platform-uischeduler:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  \- (dev.webfx:webfx-platform-util:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  +- dev.webfx:webfx-kit-javafxmedia-emul:jar:0.1.0-SNAPSHOT:compile
[INFO] |  |  +- (dev.webfx:webfx-kit-javafxbase-emul:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  +- (dev.webfx:webfx-kit-javafxgraphics-emul:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  \- (dev.webfx:webfx-platform-service:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  +- com.google.jsinterop:base:jar:1.0.1:compile
[INFO] |  |  \- (com.google.jsinterop:jsinterop-annotations:jar:2.0.2:compile - version managed from 2.0.0; omitted for duplicate)
[INFO] |  +- com.google.elemental2:elemental2-core:jar:1.2.1:compile
[INFO] |  |  +- (com.google.jsinterop:jsinterop-annotations:jar:2.0.2:compile - omitted for duplicate)
[INFO] |  |  +- (com.google.jsinterop:base:jar:1.0.1:compile - omitted for duplicate)
[INFO] |  |  \- (com.google.elemental2:elemental2-promise:jar:1.2.1:compile - omitted for duplicate)
[INFO] |  +- com.google.elemental2:elemental2-dom:jar:1.2.1:compile
[INFO] |  |  +- (com.google.jsinterop:jsinterop-annotations:jar:2.0.2:compile - omitted for duplicate)
[INFO] |  |  +- (com.google.jsinterop:base:jar:1.0.1:compile - omitted for duplicate)
[INFO] |  |  +- (com.google.elemental2:elemental2-core:jar:1.2.1:compile - omitted for duplicate)
[INFO] |  |  \- (com.google.elemental2:elemental2-promise:jar:1.2.1:compile - omitted for duplicate)
[INFO] |  +- com.google.elemental2:elemental2-media:jar:1.2.1:compile
[INFO] |  |  +- (com.google.jsinterop:jsinterop-annotations:jar:2.0.2:compile - omitted for duplicate)
[INFO] |  |  +- (com.google.jsinterop:base:jar:1.0.1:compile - omitted for duplicate)
[INFO] |  |  +- (com.google.elemental2:elemental2-core:jar:1.2.1:compile - omitted for duplicate)
[INFO] |  |  +- (com.google.elemental2:elemental2-dom:jar:1.2.1:compile - version managed from 1.1.0; omitted for duplicate)
[INFO] |  |  \- (com.google.elemental2:elemental2-promise:jar:1.2.1:compile - omitted for duplicate)
[INFO] |  +- com.google.elemental2:elemental2-promise:jar:1.2.1:compile
[INFO] |  |  +- (com.google.jsinterop:jsinterop-annotations:jar:2.0.2:compile - omitted for duplicate)
[INFO] |  |  \- (com.google.jsinterop:base:jar:1.0.1:compile - omitted for duplicate)
[INFO] |  +- com.google.elemental2:elemental2-webstorage:jar:1.2.1:compile
[INFO] |  |  +- (com.google.jsinterop:jsinterop-annotations:jar:2.0.2:compile - omitted for duplicate)
[INFO] |  |  +- (com.google.jsinterop:base:jar:1.0.1:compile - omitted for duplicate)
[INFO] |  |  +- (com.google.elemental2:elemental2-core:jar:1.2.1:compile - omitted for duplicate)
[INFO] |  |  \- (com.google.elemental2:elemental2-dom:jar:1.2.1:compile - version managed from 1.1.0; omitted for duplicate)
[INFO] |  +- dev.webfx:webfx-kit-javafxgraphics-peers:jar:0.1.0-SNAPSHOT:compile
[INFO] |  |  \- (dev.webfx:webfx-platform-console:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  +- dev.webfx:webfx-kit-javafxgraphics-peers-base:jar:0.1.0-SNAPSHOT:compile
[INFO] |  |  +- (dev.webfx:webfx-kit-javafxgraphics-peers:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  +- (dev.webfx:webfx-kit-util:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  \- (dev.webfx:webfx-platform-util:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  +- dev.webfx:webfx-kit-javafxgraphics-peers-gwt-j2cl:jar:0.1.0-SNAPSHOT:compile
[INFO] |  |  +- (dev.webfx:webfx-kit-javafxbase-emul:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  +- (dev.webfx:webfx-kit-javafxgraphics-emul:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  +- (com.google.jsinterop:base:jar:1.0.1:compile - omitted for duplicate)
[INFO] |  |  +- (com.google.elemental2:elemental2-core:jar:1.2.1:compile - omitted for duplicate)
[INFO] |  |  +- (com.google.elemental2:elemental2-dom:jar:1.2.1:compile - version managed from 1.1.0; omitted for duplicate)
[INFO] |  |  +- (com.google.elemental2:elemental2-svg:jar:1.2.1:compile - omitted for duplicate)
[INFO] |  |  +- (com.google.elemental2:elemental2-webstorage:jar:1.2.1:compile - omitted for duplicate)
[INFO] |  |  +- (com.google.jsinterop:jsinterop-annotations:jar:2.0.2:compile - omitted for duplicate)
[INFO] |  |  +- (dev.webfx:webfx-kit-javafxgraphics-peers:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  +- (dev.webfx:webfx-kit-javafxgraphics-peers-base:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  +- (dev.webfx:webfx-kit-launcher:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  +- (dev.webfx:webfx-kit-util:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  +- (dev.webfx:webfx-platform-console:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  +- (dev.webfx:webfx-platform-resource:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  +- (dev.webfx:webfx-platform-scheduler:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  +- (dev.webfx:webfx-platform-uischeduler:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  \- (dev.webfx:webfx-platform-util:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  +- dev.webfx:webfx-platform-console:jar:0.1.0-SNAPSHOT:compile
[INFO] |  |  \- (dev.webfx:webfx-platform-service:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  +- (dev.webfx:webfx-platform-scheduler:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  \- dev.webfx:webfx-platform-uischeduler:jar:0.1.0-SNAPSHOT:compile
[INFO] |     +- (dev.webfx:webfx-platform-scheduler:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |     +- (dev.webfx:webfx-platform-service:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |     \- (dev.webfx:webfx-platform-util:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] +- dev.webfx:webfx-kit-javafxmedia-registry-gwt-j2cl:jar:0.1.0-SNAPSHOT:compile
[INFO] |  +- (dev.webfx:webfx-kit-javafxmedia-emul:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  +- (dev.webfx:webfx-kit-javafxgraphics-peers:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  \- (dev.webfx:webfx-kit-javafxmedia-peers-gwt-j2cl:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] +- dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT:compile
[INFO] |  +- (dev.webfx:webfx-kit-javafxbase-emul:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  +- (com.google.jsinterop:base:jar:1.0.1:compile - omitted for duplicate)
[INFO] |  +- (com.google.elemental2:elemental2-core:jar:1.2.1:compile - omitted for duplicate)
[INFO] |  +- (com.google.elemental2:elemental2-dom:jar:1.2.1:compile - version managed from 1.1.0; omitted for duplicate)
[INFO] |  +- com.google.elemental2:elemental2-svg:jar:1.2.1:compile
[INFO] |  |  +- (com.google.jsinterop:jsinterop-annotations:jar:2.0.2:compile - omitted for duplicate)
[INFO] |  |  +- (com.google.jsinterop:base:jar:1.0.1:compile - omitted for duplicate)
[INFO] |  |  +- (com.google.elemental2:elemental2-core:jar:1.2.1:compile - omitted for duplicate)
[INFO] |  |  \- (com.google.elemental2:elemental2-dom:jar:1.2.1:compile - version managed from 1.1.0; omitted for duplicate)
[INFO] |  +- (com.google.elemental2:elemental2-webstorage:jar:1.2.1:compile - omitted for duplicate)
[INFO] |  +- org.treblereel.gwt.nio:gwt-nio:jar:1.1:runtime
[INFO] |  |  +- (com.google.elemental2:elemental2-webstorage:jar:1.2.1:runtime - version managed from 1.1.0; omitted for duplicate)
[INFO] |  |  \- (com.google.jsinterop:jsinterop-annotations:jar:2.0.2:runtime - version managed from 2.0.0; omitted for duplicate)
[INFO] |  +- com.google.jsinterop:jsinterop-annotations:jar:2.0.2:compile
[INFO] |  \- (dev.webfx:webfx-platform-javabase-emul-j2cl:jar:0.1.0-SNAPSHOT:runtime - omitted for duplicate)
[INFO] +- dev.webfx:webfx-platform-boot:jar:0.1.0-SNAPSHOT:compile
[INFO] |  +- (dev.webfx:webfx-platform-console:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  +- dev.webfx:webfx-platform-meta:jar:0.1.0-SNAPSHOT:compile
[INFO] |  |  +- (dev.webfx:webfx-platform-console:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  |  \- (dev.webfx:webfx-platform-resource:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  +- dev.webfx:webfx-platform-service:jar:0.1.0-SNAPSHOT:compile
[INFO] |  |  \- (dev.webfx:webfx-platform-util:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  +- (dev.webfx:webfx-platform-shutdown:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  \- dev.webfx:webfx-platform-util:jar:0.1.0-SNAPSHOT:compile
[INFO] +- dev.webfx:webfx-platform-console-gwt-j2cl:jar:0.1.0-SNAPSHOT:compile
[INFO] |  +- (com.google.elemental2:elemental2-dom:jar:1.2.1:compile - version managed from 1.1.0; omitted for duplicate)
[INFO] |  \- (dev.webfx:webfx-platform-console:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] +- dev.webfx:webfx-platform-javabase-emul-j2cl:jar:0.1.0-SNAPSHOT:compile
[INFO] |  +- (com.google.jsinterop:base:jar:1.0.1:compile - omitted for duplicate)
[INFO] |  +- (com.google.elemental2:elemental2-core:jar:1.2.1:compile - omitted for duplicate)
[INFO] |  \- dev.webfx:webfx-platform-service-gwt-j2cl:jar:0.1.0-SNAPSHOT:compile
[INFO] +- dev.webfx:webfx-platform-os-gwt-j2cl:jar:0.1.0-SNAPSHOT:compile
[INFO] |  +- (com.google.elemental2:elemental2-dom:jar:1.2.1:compile - version managed from 1.1.0; omitted for duplicate)
[INFO] |  \- dev.webfx:webfx-platform-os:jar:0.1.0-SNAPSHOT:compile
[INFO] |     \- (dev.webfx:webfx-platform-service:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] +- dev.webfx:webfx-platform-resource-j2cl:jar:0.1.0-SNAPSHOT:compile
[INFO] |  +- (com.google.elemental2:elemental2-dom:jar:1.2.1:compile - version managed from 1.1.0; omitted for duplicate)
[INFO] |  +- (dev.webfx:webfx-platform-boot:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  +- (dev.webfx:webfx-platform-resource:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  \- (dev.webfx:webfx-platform-util:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] +- dev.webfx:webfx-platform-shutdown-gwt-j2cl:jar:0.1.0-SNAPSHOT:compile
[INFO] |  +- (com.google.elemental2:elemental2-dom:jar:1.2.1:compile - version managed from 1.1.0; omitted for duplicate)
[INFO] |  \- (dev.webfx:webfx-platform-shutdown:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] +- dev.webfx:webfx-platform-storage-gwt-j2cl:jar:0.1.0-SNAPSHOT:compile
[INFO] |  +- (com.google.elemental2:elemental2-dom:jar:1.2.1:compile - version managed from 1.1.0; omitted for duplicate)
[INFO] |  +- (com.google.elemental2:elemental2-webstorage:jar:1.2.1:compile - version managed from 1.1.0; omitted for duplicate)
[INFO] |  \- (dev.webfx:webfx-platform-storage:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] +- dev.webfx:webfx-platform-uischeduler-gwt-j2cl:jar:0.1.0-SNAPSHOT:compile
[INFO] |  +- (com.google.elemental2:elemental2-dom:jar:1.2.1:compile - version managed from 1.1.0; omitted for duplicate)
[INFO] |  +- (dev.webfx:webfx-platform-console:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  +- (dev.webfx:webfx-platform-scheduler:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] |  \- (dev.webfx:webfx-platform-uischeduler:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] +- dev.webfx:webfx-platform-useragent-gwt-j2cl:jar:0.1.0-SNAPSHOT:compile
[INFO] |  +- (com.google.elemental2:elemental2-dom:jar:1.2.1:compile - version managed from 1.1.0; omitted for duplicate)
[INFO] |  \- (dev.webfx:webfx-platform-useragent:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] \- dev.webfx:webfx-platform-windowlocation-gwt-j2cl:jar:0.1.0-SNAPSHOT:compile
[INFO]    +- (com.google.elemental2:elemental2-dom:jar:1.2.1:compile - version managed from 1.1.0; omitted for duplicate)
[INFO]    +- (dev.webfx:webfx-platform-util:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO]    \- (dev.webfx:webfx-platform-windowlocation:jar:0.1.0-SNAPSHOT:compile - omitted for duplicate)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.775 s
[INFO] Finished at: 2024-05-24T10:00:26+01:00
[INFO] ------------------------------------------------------------------------

I don't think my dependency graph has any issue, I think the issue happens after replacements, so it's very difficult to investigate because I don't see the final effective pom after replacements, it's kind of virtual in your plugin.

Here are all the replacements I do so far on any WebFX projects such as the one above:

                <plugin>
                    <groupId>com.vertispan.j2cl</groupId>
                    <artifactId>j2cl-maven-plugin</artifactId>
                    <version>${vertispan.j2cl.plugin.version}</version>
                    <executions>
                        <execution>
                            <id>build-js</id>
                            <phase>process-classes</phase>
                            <goals>
                                <goal>build</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <!-- Note: Specifying dependencyReplacements removes the defaults provided by Vertispan -->
                        <dependencyReplacements>
                            <!-- So, we first re-apply the Vertispan defaults (from https://github.com/Vertispan/j2clmavenplugin/blob/320e5ba05f2916cb14839a829f73151776d1755b/j2cl-maven-plugin/src/main/java/com/vertispan/j2cl/mojo/AbstractBuildMojo.java#L91) -->
                            <dependencyReplacement>
                                <original>com.google.jsinterop:base</original>
                                <replacement>com.vertispan.jsinterop:base:${vertispan.jsinterop.base.version}</replacement>
                            </dependencyReplacement>
                            <dependencyReplacement>
                                <original>org.realityforge.com.google.jsinterop:base</original>
                                <replacement>com.vertispan.jsinterop:base:${vertispan.jsinterop.base.version}</replacement>
                            </dependencyReplacement>
                            <dependencyReplacement>
                                <original>com.google.gwt:gwt-user</original>
                            </dependencyReplacement>
                            <dependencyReplacement>
                                <original>com.google.gwt:gwt-dev</original>
                            </dependencyReplacement>
                            <dependencyReplacement>
                                <original>com.google.gwt:gwt-servlet</original>
                            </dependencyReplacement>

                            <!-- Then, we apply the replacements required for WebFX -->

                            <!-- Considering new GWT groupId -->
                            <dependencyReplacement>
                                <original>org.gwtproject:gwt-user</original>
                            </dependencyReplacement>
                            <dependencyReplacement>
                                <original>org.gwtproject:gwt-dev</original>
                            </dependencyReplacement>
                            <dependencyReplacement>
                                <original>org.gwtproject:gwt-servlet</original>
                            </dependencyReplacement>

                            <!-- OpenJFX javafx-base => WebFX emul module for javafx-base -->
                            <dependencyReplacement>
                                <original>org.openjfx:javafx-base</original>
                                <replacement>dev.webfx:webfx-kit-javafxbase-emul:${webfx.version}</replacement>
                            </dependencyReplacement>

                            <!-- OpenJFX javafx-graphics => WebFX emul module for javafx-graphics -->
                            <dependencyReplacement>
                                <original>org.openjfx:javafx-graphics</original>
                                <replacement>dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:${webfx.version}</replacement>
                            </dependencyReplacement>
                            <!-- There are actually several WebFX modules for javafx-graphics, but they are all merged
                             into 1 single module for J2CL, the reason being that individual replacements was causing a
                             dependency cycle in the J2CL plugin). This merged module is a kind of fat module of the
                             individual modules (that are still in used for GWT and for the development).
                             So, we need to replace all possible dependencies to the individual modules to that merged
                             module when compiling for J2CL. -->
                            <dependencyReplacement>
                                <original>dev.webfx:webfx-kit-launcher</original>
                                <replacement>dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:${webfx.version}</replacement>
                            </dependencyReplacement>
                            <dependencyReplacement>
                                <original>dev.webfx:webfx-kit-javafxgraphics-emul</original>
                                <replacement>dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:${webfx.version}</replacement>
                            </dependencyReplacement>
                            <dependencyReplacement>
                                <original>dev.webfx:webfx-kit-javafxgraphics-peers</original>
                                <replacement>dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:${webfx.version}</replacement>
                            </dependencyReplacement>
                            <dependencyReplacement>
                                <original>dev.webfx:webfx-kit-javafxgraphics-peers-base</original>
                                <replacement>dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:${webfx.version}</replacement>
                            </dependencyReplacement>
                            <dependencyReplacement>
                                <original>dev.webfx:webfx-kit-javafxgraphics-peers-gwt-j2cl</original>
                                <replacement>dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:${webfx.version}</replacement>
                            </dependencyReplacement>
                            <dependencyReplacement>
                                <original>dev.webfx:webfx-kit-javafxgraphics-registry-gwt-j2cl</original>
                                <replacement>dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:${webfx.version}</replacement>
                            </dependencyReplacement>
                            <dependencyReplacement>
                                <original>dev.webfx:webfx-kit-util</original>
                                <replacement>dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:${webfx.version}</replacement>
                            </dependencyReplacement>

                            <!-- OpenJFX javafx-controls => WebFX emul module for javafx-controls -->
                            <dependencyReplacement>
                                <original>org.openjfx:javafx-controls</original>
                                <replacement>dev.webfx:webfx-kit-javafxcontrols-emul:${webfx.version}</replacement>
                            </dependencyReplacement>

                            <!-- OpenJFX javafx-media => WebFX emul module for javafx-media -->
                            <dependencyReplacement>
                                <original>org.openjfx:javafx-media</original>
                                <replacement>dev.webfx:webfx-kit-javafxmedia-emul:${webfx.version}</replacement>
                            </dependencyReplacement>

                            <!-- OpenJFX javafx-web => WebFX emul module for javafx-web -->
                            <dependencyReplacement>
                                <original>org.openjfx:javafx-web</original>
                                <replacement>dev.webfx:webfx-kit-javafxweb-emul:${webfx.version}</replacement>
                            </dependencyReplacement>
                        </dependencyReplacements>

                        <compilationLevel>${plugin.j2cl.compilationLevel}</compilationLevel>
                        <enableSourcemaps>${plugin.j2cl.enableSourcemaps}</enableSourcemaps>
                    </configuration>
                </plugin>

It would be very helpful if your plugin could detect the Duplicate paths present errors from Closure, and then give more information about the modules with duplicate paths. But ok, let's do a manual search instead.

Here is an extract of the Closure error I'm getting without my previous fix (just the first few lines of a long list):

[INFO] Starting dev.webfx:webfx-demo-jarkanoid-application-j2cl:0.1.0-SNAPSHOT/optimized_js
[ERROR] dev.webfx:webfx-demo-jarkanoid-application-j2cl:0.1.0-SNAPSHOT/optimized_js: Duplicate paths present, ensure only one dependency contributes a given file:
[ERROR] dev.webfx:webfx-demo-jarkanoid-application-j2cl:0.1.0-SNAPSHOT/optimized_js: 	javafx/scene/layout/FlowPane$Run.java.js
[ERROR] dev.webfx:webfx-demo-jarkanoid-application-j2cl:0.1.0-SNAPSHOT/optimized_js: 	javafx/scene/layout/BackgroundPosition.java.js
...

But if I try to find such duplicate paths in gwt3BuildCache, I don't find them:

% find ./target/gwt3BuildCache -name BackgroundPosition.java.js
./target/gwt3BuildCache/0.23-SNAPSHOT/dev.webfx-webfx-kit-javafxgraphics-fat-j2cl-0.1.0-SNAPSHOT/87a0636aa6481f1b0e7a33734ad90037-transpiled_js/results/javafx/scene/layout/BackgroundPosition.java.js

I'm getting only 1 entry, so what duplicate paths is it talking about?

@niloc132
Copy link
Member

Looks like I made a mistake - a Project's key does include its classifier, if any, so if the current patch fixes your project, you do indeed seem to have two dependencies in the same project that point to the same other project.

Breaking this down a bit - your old patch was on this code

Stream<Input> jsFromJavaProjects = Stream.concat(
Stream.of(project),
scope(project.getDependencies(), Dependency.Scope.RUNTIME)
.stream()
.filter(p -> !p.isJsZip())
)
.flatMap(p -> Stream.of(
input(p, OutputTypes.TRANSPILED_JS),
// 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();

while the new patch was specific to the scope() call, which is line 157 above, or just

scope(project.getDependencies(), Dependency.Scope.RUNTIME)

So, that is the one specific line you need to distinct() to fix this issue...

Project.dependencies, for a non-test project, is set in one of two places in AbstractBuildMojo - line 259 for jszips, and 350 for all non-jszip projects. I assume the duplicate project in question is not a jszip?

Line 350 gets its items from iterating mavenProject.getArtifacts(), through filtering out unneeded items and otherwise translating each maven artifact to a j2clmavenplugin Project wrapped in a Dependency. MavenProject.getArtifacts() must only return the flattened dependency:tree results for a single scope... so there should still be no duplicates.

Are you able to see where in this flow, from MavenProject.getArtifacts() forward that your duplicate is being added?

@salmonb
Copy link
Contributor Author

salmonb commented May 24, 2024

No, I have no jszip, so must be line 350.

I will try to investigate, but my feeling is that the issue happens because I have several replacements that points to the same fat jar (see in my Vertispan plugin configuration), so the fat jar artifact is processed and added several times (which shouldn't be a problem as we both agreed), but then this causes the issue to happen (which is a bug in the plugin in my opinion).

I wanted to add a case in the dependency replacement code (which starts at line 311) to skip the replacement if it was already processed, but there is no way to know the replacement history (unless I add a HashSet to the method signature but I didn't want to modify your code too much). Or do you see another way to achieve this?

I also tried to add this test at line 348:

            if (!dependencies.contains(dep))
                dependencies.add(dep);

but this doesn't solve the issue 🤷

So I'm still not sure precisely where/when the multiple dependency is added...

@salmonb
Copy link
Contributor Author

salmonb commented May 24, 2024

Maybe some interesting info:

I replaced my fix in the scope() method with just a print of the duplicates in the returned List<Project> and got this:

Found duplicate projects: [dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxbase-emul:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT]
Found duplicate projects: [dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT]
Found duplicate projects: [dev.webfx:webfx-platform-javabase-emul-j2cl:0.1.0-SNAPSHOT, com.google.elemental2:elemental2-core:1.2.1, dev.webfx:webfx-platform-service-gwt-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-platform-service-gwt-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxbase-emul:0.1.0-SNAPSHOT, com.vertispan.jsinterop:base:1.0.1-1, dev.webfx:webfx-kit-javafxbase-emul:0.1.0-SNAPSHOT, com.vertispan.jsinterop:base:1.0.1-1, com.google.elemental2:elemental2-core:1.2.1, com.google.elemental2:elemental2-promise:1.2.1, dev.webfx:webfx-platform-util:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-platform-useragent:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-platform-service:0.1.0-SNAPSHOT, com.google.elemental2:elemental2-promise:1.2.1, dev.webfx:webfx-platform-service:0.1.0-SNAPSHOT, dev.webfx:webfx-platform-javabase-emul-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-platform-shutdown:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxmedia-emul:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxbase-emul:0.1.0-SNAPSHOT, dev.webfx:webfx-platform-resource:0.1.0-SNAPSHOT, dev.webfx:webfx-platform-scheduler:0.1.0-SNAPSHOT, dev.webfx:webfx-platform-console:0.1.0-SNAPSHOT]
Found duplicate projects: [dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT]
Found duplicate projects: [dev.webfx:webfx-platform-javabase-emul-j2cl:0.1.0-SNAPSHOT, com.google.elemental2:elemental2-core:1.2.1, dev.webfx:webfx-platform-service-gwt-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-platform-service-gwt-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxbase-emul:0.1.0-SNAPSHOT, com.vertispan.jsinterop:base:1.0.1-1, dev.webfx:webfx-kit-javafxbase-emul:0.1.0-SNAPSHOT, com.vertispan.jsinterop:base:1.0.1-1, com.google.elemental2:elemental2-core:1.2.1, com.google.elemental2:elemental2-promise:1.2.1, dev.webfx:webfx-platform-util:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-platform-useragent:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-platform-service:0.1.0-SNAPSHOT, com.google.elemental2:elemental2-promise:1.2.1, dev.webfx:webfx-platform-service:0.1.0-SNAPSHOT, dev.webfx:webfx-platform-javabase-emul-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-platform-shutdown:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxmedia-emul:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxbase-emul:0.1.0-SNAPSHOT, dev.webfx:webfx-platform-resource:0.1.0-SNAPSHOT, dev.webfx:webfx-platform-scheduler:0.1.0-SNAPSHOT, dev.webfx:webfx-platform-console:0.1.0-SNAPSHOT]
Found duplicate projects: [dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxbase-emul:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT]
Found duplicate projects: [dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT]
Found duplicate projects: [dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT]
Found duplicate projects: [dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT]

So the fat jar dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT is not the only duplicate.

Then I added some other code in scope() to remove the fat jar duplicates but not the other duplicates, and that fixed the issue again.

So it's only the fat jar duplicates that cause the problem, not the other duplicates...
Any idea why?

@salmonb
Copy link
Contributor Author

salmonb commented May 24, 2024

I just realised that Dependency.equals() was not implemented.

After implementing it, then

if (!dependencies.contains(dep))
    dependencies.add(dep);

at line 348 solves the issue at a sooner stage than my previous fix in scope().

Does that fix at line 348 + Dependency.equals() looks acceptable to you?

@niloc132
Copy link
Member

To confirm, you are saying that MavenProject.getArtifacts() contains exact duplicates? That's the root cause here and the surprise - if we need other filtering, we should understand why there are duplicates rather than just removing the first instance that matches.

Can you share the code that printed those duplicates? I don't understand what it means to have duplicates over the whole list, esp the row that doesn't have duplicates at all:

Found duplicate projects: [dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT]

Just in case this is a point of confusion: duplicates across the entire Project tree are expected and necessary. Duplicates within a single Project's getDependencies() are not. A Project's getDependencies() are all that is used to build that project, the "walk the tree and find transitive dependencies" was already performed by Maven before MavenProject.getArtifacts() was called.

@salmonb
Copy link
Contributor Author

salmonb commented May 25, 2024

Here is my code for duplicates detection:

    protected List<Project> scope(Collection<? extends Dependency> dependencies, Dependency.Scope scope) {
        List<Project> projects = dependencies.stream()
                .filter(d -> ((com.vertispan.j2cl.build.Dependency) d).belongsToScope(scope))
                .map(Dependency::getProject)
                .collect(Collectors.toUnmodifiableList());
        List<Project> duplicates = listDuplicates(projects);
        if (!duplicates.isEmpty())
            System.out.println("Found duplicate projects: " + duplicates);
        return projects;
    }

    List<Project> listDuplicates(List<Project> list) {
        List<Project> duplicates = new ArrayList<>();
        Set<Project> set = new HashSet<>();
        for (Project i : list) {
            if (set.contains(i)) {
                duplicates.add(i);
            } else {
                set.add(i);
            }
        }
        return duplicates;
    }

Project.setDependencies() is probably a better place for this code.

Anyway, can you try it on another project and let me know if you also have duplicates?

@salmonb
Copy link
Contributor Author

salmonb commented May 30, 2024

I also tried this at line 348:

            if (!dependencies.contains(dep))
                dependencies.add(dep);
            else
                System.out.println("Skipping dependency " + dep);

and then got this output (truncated but build is successful):

[INFO] Scanning for projects...
[INFO] 
[INFO] ----------< dev.webfx:webfx-demo-jarkanoid-application-j2cl >-----------
[INFO] Building webfx-demo-jarkanoid-application-j2cl 0.1.0-SNAPSHOT
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-enforcer-plugin:3.3.0:enforce (enforce-maven) @ webfx-demo-jarkanoid-application-j2cl ---
[INFO] Rule 0: org.apache.maven.enforcer.rules.version.RequireMavenVersion passed
[INFO] 
[INFO] --- maven-resources-plugin:3.3.1:resources (default-resources) @ webfx-demo-jarkanoid-application-j2cl ---
[INFO] Copying 5 resources from src/main/resources to target/classes
[INFO] Copying 0 resource from src/main/java to target/classes
[INFO] 
[INFO] --- maven-compiler-plugin:3.11.0:compile (default-compile) @ webfx-demo-jarkanoid-application-j2cl ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- j2cl-maven-plugin:0.23-SNAPSHOT:build (build-js) @ webfx-demo-jarkanoid-application-j2cl ---
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.0:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.0:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.0:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.0:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.0:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency org.openjfx:javafx-base:jar:19:provided, replacing with dev.webfx:webfx-kit-javafxbase-emul:jar:0.1.0-SNAPSHOT
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:jsinterop-annotations:jar:2.0.2:compile, no replacement
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:runtime, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:jsinterop-annotations:jar:2.0.2:runtime, no replacement
[INFO] Removing dependency org.openjfx:javafx-base:jar:mac:19:provided, replacing with dev.webfx:webfx-kit-javafxbase-emul:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxbase-emul:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency org.openjfx:javafx-graphics:jar:19:provided, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.0:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.0:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:runtime, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:jsinterop-annotations:jar:2.0.2:runtime, no replacement
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:runtime, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:jsinterop-annotations:jar:2.0.2:runtime, no replacement
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:runtime, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:jsinterop-annotations:jar:2.0.2:runtime, no replacement
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:runtime, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:jsinterop-annotations:jar:2.0.2:runtime, no replacement
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:runtime, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:jsinterop-annotations:jar:2.0.2:runtime, no replacement
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:runtime, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:jsinterop-annotations:jar:2.0.2:runtime, no replacement
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:runtime, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:jsinterop-annotations:jar:2.0.2:runtime, no replacement
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:runtime, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:jsinterop-annotations:jar:2.0.2:runtime, no replacement
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:runtime, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:jsinterop-annotations:jar:2.0.2:runtime, no replacement
[INFO] Removing dependency org.openjfx:javafx-graphics:jar:mac:19:provided, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency org.openjfx:javafx-media:jar:19:provided, replacing with dev.webfx:webfx-kit-javafxmedia-emul:jar:0.1.0-SNAPSHOT
[INFO] Removing dependency dev.webfx:webfx-kit-javafxgraphics-emul:jar:0.1.0-SNAPSHOT:compile, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
[INFO] Removing dependency dev.webfx:webfx-kit-javafxgraphics-peers:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-kit-launcher:jar:0.1.0-SNAPSHOT:compile, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency dev.webfx:webfx-platform-boot:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-meta:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-resource:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-kit-util:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-console:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-scheduler:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-shutdown:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-uischeduler:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-util:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:runtime, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:jsinterop-annotations:jar:2.0.2:runtime, no replacement
[INFO] Removing dependency org.openjfx:javafx-media:jar:mac:19:provided, replacing with dev.webfx:webfx-kit-javafxmedia-emul:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxmedia-emul:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency org.openjfx:javafx-base:jar:19:provided, replacing with dev.webfx:webfx-kit-javafxbase-emul:jar:0.1.0-SNAPSHOT
[INFO] Removing dependency org.openjfx:javafx-base:jar:mac:19:provided, replacing with dev.webfx:webfx-kit-javafxbase-emul:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxbase-emul:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency org.openjfx:javafx-graphics:jar:19:provided, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
[INFO] Removing dependency org.openjfx:javafx-graphics:jar:mac:19:provided, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency dev.webfx:webfx-kit-launcher:jar:0.1.0-SNAPSHOT:compile, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency dev.webfx:webfx-platform-boot:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-meta:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-resource:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-shutdown:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-console:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-service:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-uischeduler:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-scheduler:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-util:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:runtime, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:jsinterop-annotations:jar:2.0.2:runtime, no replacement
[INFO] Removing dependency dev.webfx:webfx-kit-launcher:jar:0.1.0-SNAPSHOT:compile, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency dev.webfx:webfx-platform-boot:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-meta:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-uischeduler:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:runtime, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:jsinterop-annotations:jar:2.0.2:runtime, no replacement
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:runtime, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:jsinterop-annotations:jar:2.0.2:runtime, no replacement
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxbase-emul:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
Skipping dependency Dependency{project=com.vertispan.jsinterop:base:1.0.1-1, scope=BOTH}
Skipping dependency Dependency{project=com.google.elemental2:elemental2-core:1.2.1, scope=BOTH}
Skipping dependency Dependency{project=com.google.elemental2:elemental2-promise:1.2.1, scope=BOTH}
Skipping dependency Dependency{project=dev.webfx:webfx-platform-javabase-emul-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
Skipping dependency Dependency{project=dev.webfx:webfx-platform-service-gwt-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxbase-emul:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency dev.webfx:webfx-kit-javafxgraphics-emul:jar:0.1.0-SNAPSHOT:compile, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency dev.webfx:webfx-kit-javafxgraphics-peers:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-kit-launcher:jar:0.1.0-SNAPSHOT:compile, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency dev.webfx:webfx-platform-boot:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-meta:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-resource:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-kit-util:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-console:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-scheduler:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-shutdown:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-uischeduler:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-util:jar:0.1.0-SNAPSHOT:compile, no replacement
Skipping dependency Dependency{project=dev.webfx:webfx-platform-javabase-emul-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:runtime, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
Skipping dependency Dependency{project=com.vertispan.jsinterop:base:1.0.1-1, scope=BOTH}
[INFO] Removing dependency com.google.jsinterop:jsinterop-annotations:jar:2.0.2:runtime, no replacement
Skipping dependency Dependency{project=com.google.elemental2:elemental2-core:1.2.1, scope=BOTH}
Skipping dependency Dependency{project=com.google.elemental2:elemental2-promise:1.2.1, scope=BOTH}
Skipping dependency Dependency{project=dev.webfx:webfx-platform-service-gwt-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
Skipping dependency Dependency{project=dev.webfx:webfx-platform-service:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency dev.webfx:webfx-kit-launcher:jar:0.1.0-SNAPSHOT:compile, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
[INFO] Removing dependency dev.webfx:webfx-kit-javafxgraphics-emul:jar:0.1.0-SNAPSHOT:compile, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
[INFO] Removing dependency dev.webfx:webfx-kit-launcher:jar:0.1.0-SNAPSHOT:compile, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency dev.webfx:webfx-platform-boot:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-meta:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-kit-util:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-service:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-shutdown:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-util:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:jsinterop-annotations:jar:2.0.2:compile, no replacement
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency dev.webfx:webfx-kit-javafxgraphics-peers:jar:0.1.0-SNAPSHOT:compile, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency dev.webfx:webfx-kit-javafxgraphics-peers-base:jar:0.1.0-SNAPSHOT:compile, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency dev.webfx:webfx-kit-javafxgraphics-peers-gwt-j2cl:jar:0.1.0-SNAPSHOT:compile, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency com.google.elemental2:elemental2-svg:jar:1.2.1:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-resource:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-kit-javafxgraphics-emul:jar:0.1.0-SNAPSHOT:compile, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency dev.webfx:webfx-kit-util:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency dev.webfx:webfx-kit-javafxgraphics-peers:jar:0.1.0-SNAPSHOT:compile, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency dev.webfx:webfx-kit-javafxgraphics-peers-base:jar:0.1.0-SNAPSHOT:compile, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency dev.webfx:webfx-kit-javafxgraphics-peers-gwt-j2cl:jar:0.1.0-SNAPSHOT:compile, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency dev.webfx:webfx-kit-javafxgraphics-emul:jar:0.1.0-SNAPSHOT:compile, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
[INFO] Removing dependency dev.webfx:webfx-kit-launcher:jar:0.1.0-SNAPSHOT:compile, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency dev.webfx:webfx-platform-boot:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-meta:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-kit-util:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-shutdown:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-util:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-kit-javafxgraphics-peers:jar:0.1.0-SNAPSHOT:compile, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency dev.webfx:webfx-platform-console:jar:0.1.0-SNAPSHOT:compile, no replacement
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:jsinterop-annotations:jar:2.0.2:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-kit-javafxgraphics-peers-base:jar:0.1.0-SNAPSHOT:compile, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency dev.webfx:webfx-kit-javafxgraphics-peers-gwt-j2cl:jar:0.1.0-SNAPSHOT:compile, replacing with dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:jar:0.1.0-SNAPSHOT
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency com.google.elemental2:elemental2-svg:jar:1.2.1:compile, no replacement
[INFO] Removing dependency dev.webfx:webfx-platform-resource:jar:0.1.0-SNAPSHOT:compile, no replacement
Skipping dependency Dependency{project=dev.webfx:webfx-kit-javafxgraphics-fat-j2cl:0.1.0-SNAPSHOT, scope=BOTH}
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Removing dependency com.google.jsinterop:base:jar:1.0.1:compile, replacing with com.vertispan.jsinterop:base:jar:1.0.1-1
[INFO] Starting com.google.elemental2:elemental2-dom:1.2.1/unpack
[INFO] Finished com.google.elemental2:elemental2-dom:1.2.1/unpack in 762ms
[INFO] Starting dev.webfx:webfx-platform-service-gwt-j2cl:0.1.0-SNAPSHOT/unpack
[INFO] Starting com.google.elemental2:elemental2-core:1.2.1/unpack
[INFO] Finished com.google.elemental2:elemental2-core:1.2.1/unpack in 140ms
[INFO] Starting dev.webfx:webfx-platform-util:0.1.0-SNAPSHOT/unpack
...

As you can see, duplicate dependencies are introduced by the replacement mechanism when different artifacts are replaced by the same replacement artifact.

This issue is solved with the condition if (!dependencies.contains(dep))
Is it an acceptable solution?

@niloc132
Copy link
Member

niloc132 commented May 30, 2024

Ah thank you, that clarifies things. So the specific bug is:

Add multiple replacement rules, where each replacement rule maps from distinct artifacts to a single artifact. In this case, each individual artifact (but not dependencies) is removed and replaced.

That really isn't what the tool is intended for, but never mind that - we should be easily able to deduplicate just at the maven level, and not bother the j2cl tooling. It looks like this can be most simply and directly achieved by modifying AbstractBuildMojo.java leading up to line 350, so that the list of dependencies that are passed in contain no duplicates. Ideally, I would make it more specific - as discussed, maven itself will not generated duplicates, only the replacement rules will. So, even more precisely, the block from 310-322 could avoid duplicating items. I'm not sure if that is worth the extra overhead though - a commented "here's what and why we're distinct()ing on" at around line 350 seems best, and least likely to imply that anything outside of maven and dependency replacements is involved.

Which is what I think you're saying here (but with comments):

This issue is solved with the condition if (!dependencies.contains(dep))
Is it an acceptable solution?

@salmonb
Copy link
Contributor Author

salmonb commented May 30, 2024

Ok, great!

Reading your comment, not sure between:

Fix 1) at line 350:

    project.setDependencies(dependencies.stream().distinct().collect(Collectors.toList()));

Fix 2) at line 348:

    if (!dependencies.contains(dep))
        dependencies.add(dep);

what's your preference? (I will add comment once you clarified)

@niloc132
Copy link
Member

I'd lean towards the second, it would make it easier for an assertion as well (that either the already-added was a dep replacement, or the one that we're skipping is), which in turn means adding a Set local var to track which are dependency replacements.

(plus {}s please on the if)

@salmonb
Copy link
Contributor Author

salmonb commented May 31, 2024

Ok, so I pushed the following changes:

  1. I removed my previous fix (i.e. call to distinct() in the scope() method)
  2. I added the dependency test at line 348 and commented it
  3. I implemented Dependency.equals() which is necessary for the previous test to work (IDEA did hashCode() at the same time)

So in the end, 2. & 3. are the only changes made by this PR to the original files.

Let me know if you're happy with that

@salmonb
Copy link
Contributor Author

salmonb commented Jun 19, 2024

As discussed on the matrix chat, I changed the code to resolve duplicate projects with different scopes and keep only the one with scope = BOTH in that case.

Because this new code doesn't rely on Dependency.equals() anymore, I removed my changes from Dependency, and in the end this PR just changes AbstractBuildMojo.

Let me know if you're happy with this last proposition.

@niloc132
Copy link
Member

Looks great, builds pass. Can you update the title/description to match the current expectations of this patch (broadly something like "deduplicate replaced dependencies")?

@salmonb salmonb changed the title Removed duplicate dependencies before calling Closure Deduplicate replaced dependencies Jun 28, 2024
@salmonb
Copy link
Contributor Author

salmonb commented Jun 28, 2024

Thanks for approving these changes.

I renamed the PR title as you suggested.

This code is now yours, so feel free to amend it (including comments) to fit your standards.

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants