On Fri, May 6, 2022 at 12:06 PM Tamás Cservenák <ta...@cservenak.net> wrote:
> Howdy, > > a lot to unravel here... > > But let me start first with the obvious: I believe you are quite > experienced, and I'd bet you did not start with Maven3, but most probably > Maven2 or even Maven1 :) The reason why I mention this, is that you use > terms from the "Maven2 era", like "reactor". Maven2 had the well known > "maven-reactor-plugin", that ceased to exist in Maven3. IMHO, let's clear > up the terms as otherwise we will just accumulate more misunderstandings. > This is far back but I believe I started with Maven 3.0 in late 2010, as I've actually never used the maven-reactor-plugin, but the term "reactor" is still in use with Maven 4 so… https://maven.apache.org/guides/mini/guide-multiple-modules-4.html > For start, let's take Maven Extensions (core or build, does not matter). > > IMHO, having them both (the tool you build with, and the source you build) > in one multi module project is IMHO wrong. That would be like a carpenter > keeping his nails and other tools along with timber in the same > box/storage, which I believe is not true. There are two kinds of extensions > in Maven: "core extension" and "build extension". Yes, both of them need to > be loaded ahead of the build. So yes, in case you keep your nails and > timber in the same box, you need to "bootstrap" things somehow (like > installing extension), as otherwise Maven will be unable to load up your > build in the first place. > > But, let me ask this: how often your tooling changes compared to the > project? In other words, are you sure your extension you use to build with, > and the project itself, are changing at the same pace? Are you sure they > should share the same "release lifecycle"? > > My typical example here (not extension, but similar intent): if we examine > Maven build, look at maven-model module. With every (even dot) release of > Maven, we generate, compile, package etc the maven-model module, while the > Maven model did not change since Maven 3.0.0 (or so, did not fact check, > but the point is there: very rarely changes). IMHO, the Maven project > should simply "move out" the maven-model from Maven build, as it does not > belong there: they do not share any release lifecycle at all. > > If we get back to extensions kept in the same build where modules are built > as well, I wonder, how often does your extension change? Does it really > change with every dot release of your project? If so, then something else > may be improved in tooling (like missing some abstraction and/or > separation). If not, it is simply in the "wrong place": why do you > build/package/deploy it every time your project changes? > > But the same thing can be applied to examples like in this thread, for > example checkstyle configuration: is this the ONLY project in your company? > If not, is this the ONLY project having this checkstyle applied (and each > project has a different one?). Maven is all about "sharing" :) > > Your next example of an annotation processor falls under the same scrutiny > as above: does it really change with every release? Let me take the problem from the other side: why should I introduce a separate release cycle for something that'll never be released on its own? If/when I use annotations and an annotation processor from the same aggregator, they're generally only some tooling to build the final "thing" (an application most of the time, as an executable JAR or a WAR). I don't (and shouldn't) really care whether/when they change, they're part of a single "project". You're suggesting that I should manage those "helpers" as a separate project with its own release cycle, and deploy the artifacts to a repo for consumption by the "real" project. What about cases where you want to test-drive a change with a "real" project? It could (should?) be as easy a creating a new aggregator POM referencing both the "project to be tested" and the "real project where you want to test it" (or directly add the "project to be tested" as a new, temporary, submodule), and change the version of the dependencies in the "real" project; run the build, it can now resolve the dependencies from the reactor and you can iterate as you find bugs, without having to 'mvn install' in between every time you make a change. I admit this is a bit "stretched" of an example, and one should actually iterate with an integration test, and/or possibly run the "real" project, temporarily, as an integration test by means of the maven-invoker-plugin (which will automate the 'mvn install' dance for you). It makes it a bit harder to debug things though. > But that said, and > reading your mail and in parallel reading m-compiler-p sources, I already > see a bug in m-compiler-p and how it resolves annotation processors: if you > look, it ends up in maven-compat (Maven2 compatibility layer) and does the > work in "Maven2 way", while you are right, this should work just fine out > of the box. Filed issue for this bug: > > https://issues.apache.org/jira/browse/MCOMPILER-496 Fwiw, as you're looking into this, https://issues.apache.org/jira/browse/MCOMPILER-272 has been marked fixed but I believe the fix introduced an unwanted behavior, as I noted in the pull request at the time: https://github.com/apache/maven-compiler-plugin/pull/40/files/cc37094621e3e125e02d4d90f0159a6589f6fa18#r630410255 So, your 2nd example (and 2nd paragraph) about the annotation processor is > IMHO a m-compiler-p bug, and shall be fixed. > The same would probably be true for the maven-javadoc-plugin and custom doclet: https://maven.apache.org/plugins/maven-javadoc-plugin/examples/alternate-doclet.html (I'm not saying it has a bug, but it works similarly to m-compiler-p's annotationProcessorPaths) > And your 3rd paragraph is a bit too vague for me. Could you, like Florent > did, create an example project that shows clearly what you want, and shows > what Maven does not as expected? > Actually I think you can see it easily with the exec-maven-plugin (which won't fork a build): 1. in parent module, declare exec-maven-plugin with skip=true and mainClass=ignored (this is my other grief wrt the linear lifecycles in Maven, using execution IDs in the invocations –exec:java@foobar– make it even worse) 2. in submoduleB, declare: <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.0.0</version> <configuration> <skip>false</skip> <includeProjectDependencies>false</includeProjectDependencies> <includePluginDependencies>true</includePluginDependencies> <executableDependency> <groupId>test</groupId> <artifactId>submoduleA</artifactId> </executableDependency> <mainClass>test.doclet.App</mainClass> </configuration> <dependencies> <dependency> <groupId>test</groupId> <artifactId>submoduleA</artifactId> <version>${project.version}</version> </dependency> </dependencies> </plugin> 3. mvn -pl submoduleB -am exec:java It fails because Maven cannot resolve submoduleA, because it has not been "built" in that invocation. You could add the "package" phase to the invocation and now Maven resolves the submoduleA JAR, but it will also also package submoduleB (before or after exec:java depending on the order you pass them on the command-line). In this case, in a small reprocase generated using a couple of org.apache.maven.archetypes:maven-archetype-simple archetype:generate invocations, exec-maven-plugin failed with a NPE when looking up the executableDependency, which is probably a bug in the plugin, but my point was to demonstrate issues with the Maven lifecycles, even prior to execute the plugin's goal. If you do not want/cannot afford to add the package phase to that invocation, your only alternative (to my knowledge) is to 'mvn install -pl submoduleA' prior to 'mvn -pl submoduleB exec:java'. -- Thomas Broyer /tɔ.ma.bʁwa.je/ <http://xn--nna.ma.xn--bwa-xxb.je/>