-
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-8015] Control the type of path where each dependency can be placed #1378
Conversation
- Refactor some `MavenProject` methods for reducing code duplication. Their behavior should be as before. - Add `@Override` annotations.
Refactor `DependencyProperties` as a type-safe map of objects instead of a map of strings. This is in anticipation for the introduction of a `PathType` property in future commits. The type of property values is specified by `DependencyProperties.Key.valueType()`.
- Add a `PathType` enumeration (actually a class for making the enumeration extensible). - Add a `DependencyResolverResult.getDispatchedPath()` method, unimplemented for now. - Move `DefaultDependencyResolverResult` as a top-level class for further developments. - Some changes in `DefaultDependencyResolver` in anticipation for further developments.
- Add a `DependencyProperties.PATH_TYPES` property. - Deprecate `DependencyProperties.FLAG_CLASS_PATH_CONSTITUENT` and `isAddedToClasspath()` methods. - Add documentation for explaining better the context-sensitive interpretation of path constituents.
- Added implementation of `DependencyResolverResult.getDispatchedPaths()`. - The code in `DefaultDependencyResolver` has been refactored, but the new code should be equivalent to the previous code for the collections that existed before this commit. The significant changes are the new code for computing the new `dispatchedPaths` map.
Add types: - Type.MODULAR_JAR: unconditionally on the module-path. - Type.CLASSPATH_JAR: unconditionally on the class-path. - And more.
CI build has been successful on Java 17 and 21, but failed on Java 11 because of the use of the |
If am not mistaken, this feature is available since Java 16? Given master is still Java 8 (build time requirement is same I think)... I'd stick with it. So please use Java 8 conformant javadoc... |
maven-artifact/src/main/java/org/apache/maven/artifact/handler/ArtifactHandler.java
Show resolved
Hide resolved
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyProperties.java
Outdated
Show resolved
Hide resolved
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyProperties.java
Outdated
Show resolved
Hide resolved
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyProperties.java
Outdated
Show resolved
Hide resolved
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyProperties.java
Outdated
Show resolved
Hide resolved
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyProperties.java
Outdated
Show resolved
Hide resolved
* @see String#intern() | ||
*/ | ||
@SuppressWarnings("unchecked") | ||
public Key<V> intern() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the whole intern
thing is needed at all.
I would suppose all references to Key
s will be done using DependencyProperties.XXX
, so I don't see a good use case for users to create duplicate instances.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The intern()
mechanism is for the org.apache.maven.internal.impl.DefaultDependency
constructor. That constructor takes in argument an instance of org.eclipse.aether.graph.Dependency
and copies its properties. But the Eclipse's properties are <String, String>
entries, so the String
keys need to be converted to DependencyProperties.Key
instances. This is the purpose of DependencyProperties.Key.forName(…)
, which provides String
→ Key
conversions. The intern()
stuff is a side-effect of the need to support that conversion. It could be removed if DefaultDependency
wasn't merely a wrapper for org.eclipse.aether.graph.Dependency
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need extensibility here ? Or could we use an enum ? @cstamas ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if we restrict the scope to standard Java tools, the extensibility is still needed for supporting the --patch-module
option, which can be seen as class-paths specific to each module. So a new enumeration value needs to be created (but not internalized) for each module to patch. An alternative design would be to make JavaPathType
an Enum
and support the --path-module
option in a separated implementation of PathType
. Whether it would make the API simpler or not is unclear to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need extensibility, as tomorrow somebody could come up with custom package that would need some special handling... story is same as in Mave3 and ArtifactHandlers... they have to be extensible, that is the whole point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to remove the intern()
method and redefine forName
as:
@Nullable
public static <T> Key<T> forName(@Nonnull String name, @Nullable Class<T> defaultType, boolean intern) {
Key<?> key;
synchronized (INTERNS) {
key = INTERNS.get(name);
if (defaultType != null) {
if (key == null) {
key = new Key<>(name, defaultType);
if (intern) {
INTERNS.put(name, key);
}
} else if (key.valueType() != defaultType && intern) {
throw new IllegalStateException("Key " + name + " already exists for a different class of values.");
}
}
}
return (Key) key;
}
The constructor could be made private
, so that the only entry point is the above method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we can do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually the above code does not fit exactly the DefaultDependencies
needs, because it forces the key to be of the type specified by defaultType
. This is the correct thing to do for above method because its return value is Key<T>
. However, DefaultDependencies
needs to first check for a key with whatever type an existing key may have. So we cannot escape the need to have two methods, one with return value Key<?>
and another one with return value Key<V>
.
I will replace the existing forName
method with a simpler one like below, checking only for existing key:
Optional<Key<?>> forName(String);
As a replacement of intern()
, I considered adding the following method:
<V> Key<V> createAndCache(String name, Class<V> valueType);
However it would not work if some plugin wants to define its own subclass of Key
, while intern()
allows this flexibility. I'm not sure if it is a flexibility worth to have however.
api/maven-api-core/src/main/java/org/apache/maven/api/JavaPathType.java
Outdated
Show resolved
Hide resolved
api/maven-api-core/src/main/java/org/apache/maven/api/PathType.java
Outdated
Show resolved
Hide resolved
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyProperties.java
Outdated
Show resolved
Hide resolved
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyProperties.java
Outdated
Show resolved
Hide resolved
api/maven-api-core/src/main/java/org/apache/maven/api/Type.java
Outdated
Show resolved
Hide resolved
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyProperties.java
Outdated
Show resolved
Hide resolved
…ges in method signatures, removal of {@return} Javadoc tags for compatibility with older compilers.
….isAddedToClassPath()` method.
…ting that interface, and the case of the `--patch-module` option an inner class named `Modular` also implementing the `PathType` interface. The latter class generalizes `--path-module` support to other kinds of module-dependent option if some appear in the future.
Applied most of above comments (still thinking for a solution about the two remaining ones). The build continues to fail on Java 11, again because of Javadoc, but this new error is more annoying. The error message is "Header used out of sequence: So it is impossible (as far as I know) to have a code compilable on both Java 11 and Java 17 when HTML headers are used in Javadoc and Javadoc checks are enabled. If compilation or Javadoc generation passes on one, it fails on the other. Workaround can be one of the following:
Which approach should we take? The last one would be the one allowing most gradual transition to newest Java versions (by allowing the use of most recent conventions right now) while preserving compatibility. |
…pendencyProperties.PATH_TYPES`.
…ompilation issues on Java 11. This commit may be reverted in the future if Java 17 become a minimal requirement for compilation.
- Refactor some `MavenProject` methods for reducing code duplication. Their behavior should be as before. - Add `@Override` annotations.
# Conflicts: # api/maven-api-core/src/main/java/org/apache/maven/api/JavaPathType.java # api/maven-api-core/src/main/java/org/apache/maven/api/Packaging.java # api/maven-api-core/src/main/java/org/apache/maven/api/PathType.java # api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolverRequest.java # maven-core/src/main/java/org/apache/maven/artifact/handler/manager/DefaultArtifactHandlerManager.java # maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependency.java # maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyProperties.java # maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolver.java # maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolverResult.java # maven-core/src/main/java/org/apache/maven/internal/impl/DefaultType.java # maven-core/src/main/java/org/apache/maven/internal/impl/DefaultTypeRegistry.java # maven-core/src/main/java/org/apache/maven/internal/impl/PathModularizationCache.java # maven-core/src/main/java/org/apache/maven/internal/impl/types/ClasspathJarTypeProvider.java # maven-core/src/main/java/org/apache/maven/internal/impl/types/EjbClientTypeProvider.java # maven-core/src/main/java/org/apache/maven/internal/impl/types/EjbTypeProvider.java # maven-core/src/main/java/org/apache/maven/internal/impl/types/JarTypeProvider.java # maven-core/src/main/java/org/apache/maven/internal/impl/types/JavadocTypeProvider.java # maven-core/src/main/java/org/apache/maven/internal/impl/types/MavenPluginTypeProvider.java # maven-core/src/main/java/org/apache/maven/internal/impl/types/ModularJarTypeProvider.java # maven-core/src/main/java/org/apache/maven/internal/impl/types/TestJarTypeProvider.java
@desruisseaux I've pushed a small rework of this PR on top of #1391 on my fork. The main change is that I removed the |
Thanks, it look good to me. I will try to add a few JUnit tests today or tomorrow. |
Note: contains some "todo" about aspects that may need clarification.
…ce method and expand an existing test case.
However, those question still need to be answered.
Added Javadoc on shortcut methods in Added a convenience method: @Nonnull
Map<PathType, List<Path>> resolveDependencies(
@Nonnull DependencyCoordinate dependencyCoordinate,
@Nonnull PathScope scope,
@Nonnull Collection<PathType> desiredTypes); Expanded an existing test case: after fetching the dependency paths, fetch again the same dependency paths but this time dispatched by type.
Note: A test if failing in the "Maven Core ITs suite" module:
I don't know what is happening here. A search for |
@desruisseaux fwiw, I've merge master branch into this branch at https://github.com/apache/maven/tree/explicit-module-path |
Thanks. Closing this pull request in favour of #1401 then. |
Introduces new API described in JIRA issue MNG-8015:
PathType
enumeration-like class.JavaPathType
subtype with values such asMODULES
,CLASSES
,DOCLET
,TAGLETS
, etc.PATH_TYPES
dependency property key (as a side-effect, theDependencyProperties
API is modified for making it type-safe).DependencyResolverRequest
API for allowing plugins to specify thePathType
that the plugin wants.DependencyResolverResult.getDispatchedPath()
method for getting the result: the paths to dependencies for each path type.Open issues
Commit 9c5e9ff (which add implementation) introduces a dependency to Java 9 or later (the
ModuleDescriptor
class). If Maven 4 decides to stay executable on Java 8, this part will need to be refactored in a multi-version JAR file. If Maven 4 decides to require Java 9 or later, thesource
andtarget
options in thepom.xml
file should be replaced by arelease
option.The implementation has no JUnit tests yet, so it may contain bug. We may want to write JUnit tests before to integrate this pull request. Waiting to see if a discussion causes a modification of this proposal before to write tests.