-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
MNG-5899 Reactor should use reduced dependency pom #69
base: master
Are you sure you want to change the base?
Conversation
-1 The old behaviour allowed inconsistency between dependencies used to calculate project build order and project dependencies used during the build. It also resulted in reparsing reactor project pom.xml files multiple times during the build, which affected build performance for larger projects. |
@ifedorenko, thanks for reviewing this. Any thoughts what we should do with the downstream implication of this change? https://issues.apache.org/jira/browse/MSHADE-206 |
I am not sure I fully understand the problem, but maven generally expects project dependencies to stay the same during the build. If you need to suppress certain storm-core dependencies from "leaking" into uber-jar projects, I think you should be able to simple mark those dependencies as optional=true (which really means "non-transitive"). |
The nice thing about how maven-shade-plugin's "dependency reduced pom" used to work, is that you could run mvn compile or mvn test from your parent module (and so maven shade plugin wouldn't kick in since it is bound to package phase), and transitive dependencies would work as normal. And you could run mvn package or mvn install from your parent module, and maven shade plugin would kick in and expose the shaded jar and dependency reduced pom to downstream modules. |
@ifedorenko Without this kind of functionality using the shade plugin with multi-module projects is a huge pain, and would require us to use an external build system to coordinate the maven builds. You have to fully build/install each shaded package independent of all other packages that depend on it. I understand that it is ugly to have the dependencies change as the build progresses. I agree it really confuses things to run dependency:tree and see it be completely different from what is actually pulled in. But it is not as bad as getting the wrong uber-jar that is missing things it needs. |
In addition to the problems mentioned above, that hack also breaks the transitive dependency collection functionality in general, because it employs a Reactor-wide cache of parsed POMs that fails to take into account the A cache with a broken key scheme is not a cache, it's a source of unexpected behavior: if any
I have a Maven plugin that computes transitive dependencies of the host project by cloning the The API to do so is public so one expects the functionality work, which it did until Maven 3.3 came along. Now because of that bug, the functionality stopped working reliably. Speed is important, sure, but correct functionality is probably even more so. So please remove that hack, and if its function is indeed necessary, then it needs to be replaced with a proper cache, one that takes the active |
Why the hack removal has not been merged yet? |
I know @jvanzyl claimed he had an alternative solution that allowed the caching but I have not seen that in over a year. I am inclined to agree with removing this hack given the side-effects on existing use-cases. The goal of a read-only model built once is noble but I fear not something that this hack implements effectively... at least without seeing evidence showing the benefits of the "hack" |
I still vote -1 on this change. While I appreciate "dependency reduced pom" usecase, I'd like the following two concerns addressed first:
Additionally, I'd like to understand expected behaviour when projects with dependency reduced pom files are excluded from the build using |
Are you serious? Such a project will never run, because of transitive dependency version conflicts -- precisely that issue we're all trying to use the shade plugin to work around. It's admirable to want your project to "scale', but let's be honest, a single project with more than a fews 10's of modules is already a monolith that should be decomposed. Can you elaborate on such a use-case? I'm really quite surprised to hear of this as an explicit objective. |
I am dead serious. I am not at liberty to disclose exact numbers, but lets say our main codebase is in the same ballpark if we allow some room for growth. So 5K modules is not "aspirational pipe dream" kind of goal but very much a real-life requirement we have. (if you are interested, I can provide some details about how we use Maven for a project of this size, but maven dev list is probably a better place to talk about it). Even in opensource some projects apparently have ~700 modules. |
That might be a practical limitation right now, but I wouldn't mind having a dynamic build order. The two things that should matter are that builds complete, and have the same final outcome. Dealing with the issues of being able "pull up" a dependency in the reactor, and knowing what can be built / is waiting on something else to be built might actually benefit scalability with parallel executions. Seems like there is a more important design question here - should a project, when built and installed to a repository, then depended on by a completely separate build behave the same when it is included in a reactor? If you can create an artifact, and a custom pom for install / deployment to a repository that differs from the project pom, then to my mind that should be what is seen by any module including it as a dependency, even in the same reactor. The concern is about adding new dependencies, and whilst that is technically possible, I'm not sure that it needs to be supported - it could have just been made a dependency of the project anyway. The real issue - particularly with the shade plugin - is that you want to embed things in an artifact, and not have other projects having to try and pull them in as dependencies. To be honest, it would actually be better if this was native to the pom, rather than part of the shade plugin, because then you could express what dependencies you want to embed, and this information would then be communicated to other projects depending on it. Then they would not only not pull in the transitive dependency for the embedded code, they would also be able to determine if the embedded version is compatible with their requirements. |
"Richard Sand" on dev@maven.apache.org replies: I had tried to use the shade plugin along with the install & deploy=20 true Not sure if this adds anything to the thread but it worked for me -Richard ------ Original Message ------ |
There are issues with that:
My original proposal for a solution was to allow a plugin to advertise dependency reduction of a pom (or additional GAV production). For dependency reduction, Maven would enforce specific rules such as "no new dependencies" and the build plan would be unmodified. For additional GAV production, there would have to be strict rules on the new GAV (such as being evaluated based entirely on properties available to general project GAV computation - i.e. nothing injected into the build by another plugin) and similar rules on the new GAV pom (i.e. only ever a subset of the GAV it is being generated from) That would allow us to create the build plan reflecting the potential behaviours of the shade plugin (as well as the flatten plugin) before any plugin executions but allow plugins to do what is necessary... but my suggestion was shot down last time |
Is there any update on this topic? |
Tested and working on Paper without noticeable problems. `commandapi-(paper/spigot)-(shade/plugin)-mojang-mapped` modules removed. Spigot shade/plugin are now only spigot-mapped since Spigot servers are always spigot-mapped. Paper shade/plugin contain spigot-mapped nms for pre 1.20.5 and mojang-mapped nms for 1.20.5+, which is compatible with official Paper server jar downloads. Paper 1.20.5/6 and 1.21 relocate the mojang-mapped nms common classes they need to a separate package to avoid conflicting with the spigot-mapped versions. The CommandAPI Paper plugin (and plugins that shade Paper CommandAPI) marks itself as mojang-mapped so the Paper server does not remap these classes. Mojang-mapped classes that get remapped do not work. On Paper, MojangMappedVersionHandler now has to return true/false based on the detected server version. Also made sure Brigadier wasn't shaded into the Spigot jar, and the preprocessor classes weren't shaded into Paper and Spigot. Further exploration: - This 9-year-old Maven bug apache/maven#69 is annoying. If you build the paper-plugin module individually, it gets shaded correctly. However, if you build the whole project, extra classes get included and mess up the build. For example, the un-relocated version of classes from `commandapi-bukkit-1.21:mojang-mapped` get included transitively through `commandapi-paper-1.21`, even though that dependency is not present in the dependency reduced pom because they are supposed to be relocated by the shade plugin. Perhaps there is a better way to set things up so this can be avoided (I wonder if gradle has this issue :P). - These changes require plugins that shade `commandapi-paper-shade` to mark their plugins as mojang-mapped. This would have to be mentioned in the docs. Also, it may be possible that a developer would for some reason have to mark their plugins as spigot-mapped. In this case, we may want to provide a `commandapi-paper-shade-spigot-mapped` module, so that 1.20.5+ nms can be properly passed though Paper's automatic remapping. - Currently on `dev/dev`, `commandapi-bukkit-plugin` and `commandapi-bukkit-shade` support Spigot and Paper in one jar. On `dev/commandapi-paper`, this is no longer the case. It seems fine to do this for the plugins, since a server owner can just drop in the correct jar. However, for plugins that shade the CommandAPI, if they want to support both Spigot and Paper, they are currently forced to produce two jars as well. Perhaps there could be a `commandapi-bukkit-shade` module with a CommandAPIVersionHandler that loads Spigot or Paper nms based on the detected server version. This would give shade-based developers back the ability to create a single jar that supports both Spigot and Paper. - Other things mentioned in added comments
No description provided.