Vertispan / j2clmavenplugin

Maven plugin to launch new J2CL compilation
https://vertispan.github.io/j2clmavenplugin/
Apache License 2.0
53 stars 26 forks source link

Deduplicate replaced dependencies #259

Open salmonb opened 4 months ago

salmonb commented 2 months ago

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 commented 2 months ago

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 commented 2 months ago

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 commented 2 months ago

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 https://github.com/Vertispan/j2clmavenplugin/blob/97ae186a10983d2e90cbc9b769a155eeab15bb8a/j2cl-tasks/src/main/java/com/vertispan/j2cl/build/provided/ClosureTask.java#L155-L168

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 commented 2 months ago

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 commented 2 months ago

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 commented 2 months ago

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 commented 2 months ago

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 commented 2 months ago

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 commented 1 month ago

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 commented 1 month ago

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 commented 1 month ago

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 commented 1 month ago

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 commented 1 month ago

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 commented 1 month ago

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 commented 3 weeks ago

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 commented 3 weeks ago

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!