Le 2024-01-03 à 09 h 08, Romain Manni-Bucau a écrit :

(…snip…) just to answer trivially to "But if an artifact is included, it should (at least by default) always be placed consistently on the class-path or module-path.", it is obvious it is not the case for several plugins like surefire (…snip…)

I would like to see a proof in the form of an "hello world" application, compiled and executed on the command-line with inconsistent options, showing that it works and can only work with the inconsistency. I'm not talking about dependencies added or removed such as JUnit (this is handled by scopes). I'm talking about the same dependency being on the class-path at compile time but the module-path at runtime, or conversely.


(…snip…) where ultimately you want to test both but default on classpath is fine in 80% of cases even if a module (…snip…)

No, defaulting on the classpath is fine only if the library developers applied workarounds. This point have been proven by an executable test case months ago. This is an objective fact, not an opinion. So I'm not sure why you keep bringing an argument that has been demonstrated to be technically false. Is it because you think that the Java ecosystem should be forced to keep class-path compatibility?


(…snip…) lib will always priviledge its main consumers - classpaths today - and enable others - jpms (…snip…)

Libraries can do that if they want, but should not be forced to do so. Maven 3 practically forces libraries to be designed for class-path (again: demonstrated by executable test case). The proposal for Maven 4 aims to remove this restriction by making module-path as easy as class-path. It should be transparent for most users, with enough configuration power for resolving common problems when necessary. I believe that the current proposal achieve those goals. If it is not the case, again let prove that with an executable test case against a prototype.


(…snip…) using the classpath will enable to fall in an area you can use more reflection (…snip…)

Enabling more reflection in a module is the purpose of the --add-opens option, so we don't need class-path for that. But anyway, if a developer really wants to force the use of class-path, it is still possible with the proposal.


(…snip…) even plain exec plugin which does not handle modules in java mode so will ignore - by design - several of the options you added.

Why would the exec plugin wants to ignore the module-path by design?


The first concern of my previous answer I mentionned was not "did you put logic" but "you hardcoded the dispatching as _isAddedtoClasspath_ did before" - even if the logic is more complex now - so basically we stay in the same status quo where plugins still have to redo all the dispatching logic themselves and, as you pointed out, since the number of consumers ("paths") becomes more serious it will need to be shared (maven-shared or alike) to be consistent and not too laborious probably.

It is not exactly the dispatching that is hard-coded. Let see class-path, module-path, etc. as sets. Each dependency declares in which set(s) they belong. This is currently done by boolean flags, but could be generalized by strings or enumerations instead. A plugin could create dependencies and declare that they belong to a new set of their own. Even if Maven core does not know that plugin-specific set, it is not a problem because when a dependency belong to only one set, there is no ambiguity. If a dependency said "I can be on the class-path and nowhere else", then the code will place that dependency on the class-path, period. No analysis, no hard-coded fancy things. The more complex logic happens when a dependency declares that it belong to two or more sets. If a dependency said "I can be on the class-path OR the module-path", then a choice needs to be done. This is where the hard-coded logic happens (in addition of --patch-module special case). Consequently, plugins can force their own logic by making sure that each dependency belongs to only one set. Alternatively, the rules for choosing between two or more sets could be a plugable mechanism if desired.


* we need to ensure these dependency sets ("types" today) are extensible from the pom directly, without any code or extensions to let plugins consume more

Type (at least in the pre-December 14th approach) is another level on top of sets. The sets are specified (indirectly, through boolean flags) by DependencyProperties. Types specifies (indirectly) list of sets. For example the "jar" type said (indirectly) that dependencies of this type belong to both the "classpath set" and the "module-path set". The "test-jar" type said (indirectly) that dependencies of this type belong to both "classpath set" and "patch-module set". Because those types specify two sets, this is where a code logic is needed for making a choice. By contrast, "classpath-jar" specifies (indirectly) only the "classpath set", so no code logic will apply to dependencies of this type. This is how developers can force the use of class-path in this example.


* we need to review we still need scopes or if we just bind a set name to a phase which would simplify the build by limiting the concepts

I think that types and scopes are two orthogonal axes. Having those orthogonal axes avoid the need for "javac-classpath", "javadoc-classpath", "java-classpath", etc. We have only a single "classpath" set, intersected with the scope. If scopes were removed, having sets with names like "javac-classpath" would be reproducing the two axes, but in the name ("javac" = compile-time scope, "classpath" = path type) instead of in the model.


(…snip…) my goal is to (…snip…) not hardcode concepts in core and not solve the original challenge which is that a new type of path needs to recode in core.

New paths do not need recoding Maven core. Only *choices between two or more paths* need to be coded, and even that part can be made plugable in a next version if desired.


Making it even more concrete: how to you handle the _webjars_ path in your proposal?

Create a new PathType WEB_JAR constant in the plugin. Put that PathType in the DependenciesProperties object of your dependencies. That's all. It requires replacing the current boolean flags by a single property associated to PathType[], but this is a minor change that I mentioned in yesterday email. Same applies to npm, cargo, composer, etc. No need to modify Maven core for supporting those types. To repeat: if each type is associated to only one PathType, no new code is needed at all. Only if some types are associated to two or more PathType (plus the --patch-module special case), some code for making choice is needed, and this code could be plugable if desired.

    Martin

Reply via email to