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