简体   繁体   English

maven-dependency-plugin是否比其他maven使用其他类型的工件解析?

[英]Does the maven-dependency-plugin use some other kind of artifact resolution than the rest of maven?

If I use the maven-dependency-plugin plugin, than I can't use a version range. 如果我使用maven-dependency-plugin插件,那么我就无法使用版本范围。 Also it seems the version of a there defined artifact doesn't get updated though a newer version is in the remote repository. 此外,虽然较新版本在远程存储库中,但似乎未定义工件的版本。

Why is that so? 为什么会这样?

Uses the maven-dependency-plugin some other mechanism than the rest of maven to resolve dependencies? 使用maven-dependency-plugin除了其他maven之外的其他一些机制来解决依赖关系? And if that is the case, why? 如果是这样的话,为什么呢?

Here a example: 这是一个例子:

I have created a project org.example:org.example.simple.project1:jar and put it in the repository using the versions 1.0.0-SNAPSHOT, 1.0.0, 1.0.1 and 1.1.0-SNAPSHOT 我创建了一个项目org.example:org.example.simple.project1:jar并使用版本1.0.0-SNAPSHOT,1.0.0,1.0.11.1.0-SNAPSHOT将它放入存储库

I have now configured the dependency plugin in the following way: 我现在以下列方式配置依赖插件:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>unpack-stuff<id>
            <phase>initialize</phase>
            <goals>
                <goal>unpack</goal>
            </goals>
            <configuration>
                <artifactItems>
                    <artifactItem>
                        <groupId>org.example</groupId>
                        <artifactId>org.example.simple.project1.</artifactId>
                        <version>[1.0,1.1)</version>
                        <type>jar</type>
                        <overWrite>true</overWrite>
                        <outputDirectory>target/stuff</outputDirectory>
                        <includes>**/*.*</includes>
                    </artifactItem>
                </artifactItems>
            </configuration>
        </execution>
    </executions>
</plugin>

If the dependency resolution would be the same as in the other dependencies, the version shoud resolve (at least in my opinion) to 1.0.1 . 如果依赖关系解析与其他依赖关系相同,那么版本应该(至少在我看来)解析为1.0.1

Instead I get the following exception: 相反,我得到以下异常:

[ERROR] FATAL ERROR
[INFO] ------------------------------------------------------------------------
[INFO] version was null for org.example:org.example.simple.project1.
[INFO] ------------------------------------------------------------------------
[INFO] Trace
java.lang.NullPointerException: version was null for org.example:org.example.simple.project1.
at org.apache.maven.artifact.DefaultArtifact.getBaseVersion(DefaultArtifact.java:362)
at org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout.pathOf(DefaultRepositoryLayout.java:47)
at org.apache.maven.artifact.repository.DefaultArtifactRepository.pathOf(DefaultArtifactRepository.java:110)
at org.apache.maven.artifact.resolver.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:125)
at org.apache.maven.artifact.resolver.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:74)
at org.apache.maven.plugin.dependency.fromConfiguration.AbstractFromConfigurationMojo.getArtifact(AbstractFromConfigurationMojo.java:242)
at org.apache.maven.plugin.dependency.fromConfiguration.AbstractFromConfigurationMojo.getProcessedArtifactItems(AbstractFromConfigurationMojo.java:143)
at org.apache.maven.plugin.dependency.fromConfiguration.UnpackMojo.getProcessedArtifactItems(UnpackMojo.java:138)
at org.apache.maven.plugin.dependency.fromConfiguration.UnpackMojo.execute(UnpackMojo.java:88)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:453)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:559)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:500)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:479)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:331)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:292)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:142)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:336)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:129)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:301)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4 seconds
[INFO] Finished at: Mon Aug 03 17:21:41 CEST 2009
[INFO] Final Memory: 13M/133M
[INFO] ------------------------------------------------------------------------

Ok here's the real answer (I wrote the dependency plugin): 好的,这是真正的答案(我编写了依赖插件):

The unpack and copy goals have to replicate some of the core resolution code. 解包和复制目标必须复制一些核心解析代码。 Unfortunately that resolution code was not really in a useable form api-wise. 不幸的是,解析代码实际上并不是一种可用的形式。 Because of this, those goals do not handle version ranges, and also don't resolve artifacts directly from the reactor (I frankly just never implemented them because it broke too many of the existing use cases, yeah core the resolution code was that bad) 因此,这些目标不能处理版本范围,也不能直接从反应堆中解析工件(我坦率地说从未实现它们,因为它打破了太多的现有用例,是核心解决方案代码那么糟糕)

A much better approach is to use the xxx-dependencies forms of these goals. 更好的方法是使用这些目标的xxx依赖形式。 These goals ask Maven to do the resolution before they are invoked and so it's 100% compatible. 这些目标要求Maven在调用之前执行解决方案,因此它是100%兼容的。 You can use the filters like the groupId and artifactId filter to effectively get the list of artifacts you want and the end result will be the same. 您可以使用像groupId和artifactId过滤器这样的过滤器来有效地获取所需的工件列表,最终结果将是相同的。

The copy and unpack are definately more flexible and were intended for a much simpler use case I had at the time. 复制和解压缩肯定更灵活,旨在用于我当时使用的更简单的用例。 Knowing what I know now, I probably would have implemented it more like the xxx-dependencies forms to start with. 知道我现在所知道的,我可能会更像是xxx-dependencies表单来实现它。

All that said, in Maven 3, the resolution code is finally completely decoupled...the dependency plugin driving most of the use cases needed for this. 总而言之,在Maven 3中,解析代码最终完全解耦...依赖插件驱动了大部分用例。 I'll be starting to work on a new version of the plugin to fully leverage this soon...and while it will require maven 3, it will finally work 100% with all the goals. 我将开始研究新版本的插件,以便尽快充分利用它...虽然它需要maven 3,但它最终将100%完成所有目标。

The dependency plugin uses the same resolution mechanism as everything else. 依赖插件使用与其他所有内容相同的解析机制。 It may be that your repositories are not updating the metadata because the is set to never or weekly or something. 可能是您的存储库未更新元数据,因为它设置为neverweekly或其他内容。 You can force Maven to refresh all the remote repository metadata by running with a -U. 您可以通过使用-U运行来强制Maven刷新所有远程存储库元数据。

The dependency plugin also doesn't overwrite downloaded dependencies by default if they already exist in the target. 如果目标中已存在依赖性插件,则默认情况下也不会覆盖下载的依赖项。 You can do a clean or configure the goal to force overwrites. 您可以执行清理或配置目标以强制覆盖。 There are three parameters you can set to true: overWriteIfNewer , overWriteReleases , and overWriteSnapshots . 您可以将三个参数设置为true: overWriteIfNeweroverWriteReleasesoverWriteSnapshots See the documentation for more details. 有关详细信息,请参阅文档

Edit: based on your updated question, the problem is that you are using a dependency range. 编辑:根据您更新的问题,问题是您正在使用依赖范围。 Ranges are fine as long as there is something to resolve the version (for example you have the version defined in the parent project or in your dependencies section). 只要有解决版本的内容(例如,您在父项目或依赖项部分中定义了版本),范围就可以了。 If you change the range to an exact version, or use one of the LATEST or RELEASE keywords , Maven will be able to resolve the version number (though be aware that those keywords carry their own risks. 如果您将范围更改为精确版本,或使用其中一个LATEST或RELEASE关键字 ,Maven将能够解析版本号(但请注意,这些关键字会带来风险。

I'd recommend defining a dependencyManagement section in your parent with the versions you use, then your projects can inherit those versions. 我建议在您的父级中使用您使用的版本定义dependencyManagement部分,然后您的项目可以继承这些版本。 I answered another question about this recently, I'll post a link if I find it 我最近回答了另一个问题,如果我找到它,我会发布一个链接

The problem with dependency ranges is that you did not specify one of the versions you used. 依赖项范围的问题是您没有指定您使用的某个版本。 If you specified the range as [1.0.0,1.1.0-SNAPSHOT) then it may do as you expect. 如果您将范围指定为[1.0.0,1.1.0-SNAPSHOT],那么它可能会按预期执行。 You can't assume 1.0 and 1.1 will resolve to 1.0.* and 1.1.* which is what you seem to imply. 您不能假设1.0和1.1将解析为1.0。*和1.1。*这是您似乎暗示的。

As of version 3.0.0 the maven-dependency-plugin now supports this out of the box. 从版本3.0.0开始,maven-dependency-plugin现在支持开箱即用。 Credits and thanks to Brian_Fox 致谢并感谢Brian_Fox

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM