Maven 使用错误的位置下载插件 pom

发布于 2024-12-08 13:57:07 字数 1974 浏览 0 评论 0原文

(这个问题也在 Maven 用户邮件列表上被问到)

我最近遇到了一个奇怪的问题,我什至无法判断问题的原因或来源。如果有人能给我一些指导,那就太好了:(

故事可能有点长)

我正在使用 Nexus 1.8.0 作为我们公司的存储库管理器。我使用它作为外部存储库的代理,并托管我们自己的存储库。 Nexus 中有很多存储库。我有一个存储库组(我们称之为PUBLIC),它对所有公共存储库进行分组,包括 Maven Central、Codehaus 等。 还有另一个存储库组(我们称之为 EXT),我们将其放置在第 3 方工件中。

在我们的项目中,我们使用了org.codehaus.mojo:native2ascii-maven-plugin。 由于当时的一个错误,我没有使用公开可用的 org.codehaus.mojo:native2ascii-maven-plugin:1.0-alpha-1,而是修复了该错误并将其部署到我们的 < strong>EXT 存储库,并将其命名为 org.codehaus.mojo:native2ascii-maven-plugin:1.0-alpha-1.1 (即使用了新的版本号1.0-alpha-1.1 而不是 1.0-alpha-1

这已经运行良好好几年了。

然而最近,一位新开发人员尝试使用 Maven 2.2.1 获取代码并进行构建。奇怪的事情发生了:构建失败。通过检查 mvn -X clean install 的结果,它指出 native2ascii-maven-plugin:1.0-alpha-1.1 的 POM 无法从 PUBLIC 下载,因此它将使用默认的空 POM,这会导致构建问题。

通过检查本地存储库,我发现只下载了 native2ascii-maven-plugin:1.0-alpha-1.1 的 JAR。我确信 PUBLIC 存储库中没有 native2ascii-maven-plugin:1.0-alpha-1.1,并且 JAR 的 SHA 与 native2ascii-maven 匹配-plugin:1.0-alpha-1.1在EXT中。看起来,Maven 能够从 EXT 存储库正确下载 JAR,但是当它之后尝试下载 POM 时,Maven 错误地认为应该从 PUBLIC 下载 JAR 。由于PUBLIC不包含1.0-alpha-1.1,Maven假设没有POM。

我在 settings.xml 中的 PUBLIC 之前定义了 EXT 存储库。更奇怪的是,我试图阻止 PUBLIC 在 Nexus 中访问 native2ascii-maven-plugin。 Maven,不是从存储库 EXT 获取 POM,而是直接从 central 获取。最后我添加PUBLIC作为central的镜像,Maven可以正确构建,因为EXT是唯一包含native2ascii的repo -maven-插件。 Maven 似乎尝试从其他包含 native2ascii-maven-plugin 的存储库下载 POM,无论版本号如何,除了 EXT

我根本无法理解为什么会发生这种情况。这已经使用了很多年,甚至几周前它都很好(我有其他新开发人员,他们可以在几周前正确下载该插件)。有人可以指导我问题的可能原因吗?我既没有更改我的存储库中的任何内容,也没有更改 Maven 的版本。为什么 Maven 的“下载”行为突然改变了?

(This question is asked on Maven User mailing list too)

I have recently faced a strange problem, that I cannot even able to judge the cause or source of problem. It will be great if someone can give me some direction:

(The story may be a bit long)

I am using Nexus 1.8.0 as our company's repository manager. I use it as proxy of external repo, and hosting our own repository.
There are many repositories in Nexus. I have one repository group (let's call it PUBLIC) which groups all public repositories, including maven central, codehaus etc.
There is another repository group (let's call it EXT) which we put 3rd party artifacts.

In our project, we used org.codehaus.mojo:native2ascii-maven-plugin.
Due to a bug at that time, instead of using the publicly available org.codehaus.mojo:native2ascii-maven-plugin:1.0-alpha-1, I have fixed the bug and deploy it to our EXT repository, and called it org.codehaus.mojo:native2ascii-maven-plugin:1.0-alpha-1.1 (i.e. used a new version number 1.0-alpha-1.1 instead of 1.0-alpha-1)

This have been running fine for several years.

However recently a new developer tries to get the code and build, using Maven 2.2.1. Strange things happened: the build failed. By inspecting result of mvn -X clean install, it states that POM of native2ascii-maven-plugin:1.0-alpha-1.1 cannot be downloaded from PUBLIC, therefore it will use a default emtpy POM, which cause the build problem.

By inspecting the local repository, I found that only the JAR of native2ascii-maven-plugin:1.0-alpha-1.1 was downloaded. I am sure that there is no native2ascii-maven-plugin:1.0-alpha-1.1 in PUBLIC repository, and the SHA of the JAR matches with native2ascii-maven-plugin:1.0-alpha-1.1 in EXT. It seems that, Maven is capable to download the JAR correctly from EXT repo, but when it tries to download the POM afterwards, Maven mistakenly think that it should be downloaded from PUBLIC. Because PUBLIC do not contains 1.0-alpha-1.1, Maven assume there is no POM.

I have EXT repo defined before PUBLIC in my settings.xml. What even more strange is, I tried to block accessing in Nexus for native2ascii-maven-plugin from PUBLIC. Maven, instead of getting the POM from repository EXT, it get from central directly. At last I add PUBLIC as mirror for central, and Maven can build correctly, because EXT is the the only repo that contains native2ascii-maven-plugin. Maven seems tries to download the POM from every repository else which contains native2ascii-maven-plugin in despite of the version number, except from EXT

I simply cannot understand why this will happen. This have been used for years, and it used to be fine even several weeks before (I have other new developers, who can correctly download the plugin, several weeks ago). May anyone guide me the possible cause of the problem? I have neither changed anything in my repo, nor changed version of Maven. Why Maven's "download" behavior suddenly changed?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

月下客 2024-12-15 13:57:07

很难说。

首先是我关于为什么它不再起作用的理论。我猜这“工作了多年”,因为它曾经工作过,然后所有内容都在您的本地存储库中(/.m2/repository)。后来,有些东西坏了,但你从来没有注意到,因为你的一切都是本地的。新开发人员没有填充的本地存储库,因此当他们第一次构建时,他们遇到了失败。

现在我的建议可能不适合你。使用 Nexus 时,我认为最好创建一个链接所有其他存储库的“组”存储库,并配置该组以排序链接存储库的优先级。因此,对于您来说,在组中,您将首先列出 EXT,然后列出 PUBLIC。您的 POM 和/或设置将仅引用组存储库。这可能只是重复您已经通过其他方式所做的事情,但至少它将排序规则移至 Nexus 中。我会重命名您的本地存储库(以便您可以在必要时恢复)并尝试重新构建以查看一切是否正确解决。

您可能需要考虑像 Hudson 这样的持续构建工具,它会定期删除自己的本地存储库,以便您可以更快地发现此类问题。

It's hard to say.

First my theory on why it no longer works. I am guessing this "worked for years" because at one time it worked, and afterwards everything was in your local repository (<home>/.m2/repository). Later, something broke, but you never noticed because you had everything local. The new developer did not have a populated local repository so when they built for the first time, they had failures.

Now my suggestion which may not work out for you. When using Nexus, I think its best to create a single "group" repository that links in all other repositories, and configure the group to order the priority of the linked repositories. So for you, in the group, you would list EXT first, then PUBLIC. Your POMs and/or settings would reference only the group repository. This may just duplicate what you are already doing through other means, but at least it is moving the ordering rules up into Nexus. I would rename your local repository (so you can revert back if necessary) and try re-building to see if everything resolves correctly.

You might want to consider a continuous build tool like Hudson that periodically deletes its own local repository so you can catch issues like this sooner.

生寂 2024-12-15 13:57:07

最后我终于找到了问题的“原因”。这是由于我的错误以及 Maven 的未知行为造成的。我将其添加为答案,以方便其他人将来参考。

他们的关键问题是我错过了这个特定项目的插件版本(我确实为其他项目放置了相应的pluginManagement,以及这个项目的其他插件......我想知道这次我怎么会犯这个错误)

重现问题的方法:

  1. 一个单独的存储库来存储插件(在我的例子中,org.codehaus.mojo:native2ascii-maven-plugin:1.0-alpha-1.1
  2. 在项目 POM 中,添加插件,不带版本。例如,

    <插件>;
        <插件>
            org.codehaus.mojo;
            native2ascii-maven-plugin;
        <插件>
    
    
  3. 在settings.xml 中,避免定义镜像(即settings.xml 仅包含存储库和pluginRepositories 的列表)。

通过这样的设置,首先清除本地存储库。然后构建项目。构建后,检查本地存储库中该插件的目录(在我的例子中 .m2\repository\org\codehaus\mojo\native2ascii-maven-plugin\1.0-alpha-1.1),你会发现只有 JAR 存在,没有相应的 POM。 (由于Maven成功获取了settings.xml中pluginRepositories对应的插件JAR,但试图从一个奇怪的位置获取POM)

使用相同的设置,将版本放入项目POM中,清理本地存储库,然后再次构建。现在一切都很好。

即使对于最近干净的 CI 环境也能正常工作的原因可能是由于其他“正确”项目正确下载了插件,该插件可以被这个“不正确”项目使用。定期清除 CI 中的本地存储库对此也没有太大帮助,因为对于许多项目来说,其他“正确”项目早于“不正确”项目构建的机会总是非常高。

Maven 这种行为背后的原因仍然未知,但至少在“正确”的 POM 中(正确声明了插件版本),Maven 工作得很好。不过我会将此作为 Maven 的一个问题提出。

At last I managed to find out the "cause" of the problem. It is due to my fault, combined with still-unknown behavior of Maven. I add this as an answer to ease future reference for other people.

They key problem is that I missed plugin version for this specific project (I did put corresponding pluginManagement for other projects, and other plugins for this project... I wonder how come I made this mistake this time)

The way to reproduce the problem:

  1. A separate repository to store the plugin (in my case, org.codehaus.mojo:native2ascii-maven-plugin:1.0-alpha-1.1)
  2. In project POM, add plugin, without version. For example,

    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>native2ascii-maven-plugin</artifactId>
        <plugin>
    </plugins>
    
  3. in settings.xml, avoid defining mirrors (i.e. the settings.xml contains list of repositories and pluginRepositories only)

With such setup, first purge the local repository. Then build the project. After build, inspect the directory in local repository for that plugin (in my case .m2\repository\org\codehaus\mojo\native2ascii-maven-plugin\1.0-alpha-1.1), you will find only the JAR presents, without corresponding POM. (Caused by Maven successfully get the plugin JAR corresponding to the pluginRepositories in settings.xml, but trying to get the POM from a weird location)

With the same setup, put the version in project POM, clean up the local repo, and build again. Everything is fine now.

The reason for work fine even for a recently clean CI environment, is probably due to other "correct" project made the plugin downloaded correctly, which can be used by this "incorrect" project. A periodic purge in local repository in CI won't necessary help much on this too because for that many projects, the chance is always very high for other "correct" project build earlier than that "incorrect" project.

The reason behind such behavior of Maven is still unknown, but at least in a "correct" POM (with plugin version correctly declared), Maven works fine. I will raise this as a issue for Maven though.

我最亲爱的 2024-12-15 13:57:07

我首先同意 SingleShot 的持续集成 - 即使是一个简单的冒烟测试,您只需在主干上编译和运行单元测试 - 也会阻止您陷入假设的情况,因为构建可以在一台机器上运行,它对另一个不起作用。

这几年来一直运行良好。

这就是 Maven 存储库的亮点 - 您所需要做的就是成功下载一次,然后就可以永远使用了。仅仅因为它在本地存储库中成功运行并不意味着它正在运行。

几个月前还好(因为我已经迁移了 CI 服务器,并且我有一个干净的环境要构建,一切都很好)。

有趣的。所以我的理论是然后去确保新的开发人员设置正确 - settings.xml 文件就位并且正在被读取(我有过这样的情况:settings.xml 在那里,但是在错误的位置)地方!)。这是一个简单的问题,但是如果没有settings.xml,Maven 也不会失败,它只是使用一个默认值,这可能会让你看到鬼。

I'd start off by agreeing with SingleShot in that Continuous Integration - even a simple smoke test where you simply compile and run unit tests on the trunk - would have prevented you getting into the situation of assuming that the because the build works on one machine, it does not work on the other.

This have been running fine for several years.

That's the kicker with Maven repositories - all you need to do is download it once succesfully, and you'll be forever good to go. Just because it's been working successfully from your local repository doesn't mean it was working.

It is fine several months ago (coz I have migrated our CI server and I have a clean env to build, and everything is fine).

Interesting. So my theory would be then to go and make sure the new developer is set up correctly - that the settings.xml file is in place and is being read (I've had instances that the settings.xml is THERE, but in the wrong place!). It's a simple one, but Maven does not fail if there's no settings.xml, it just uses a default that may have you seeing ghosts.

一场信仰旅途 2024-12-15 13:57:07

您提到您使用maven 2.2.1,我只能要求您仔细检查,我们在从内部存储库下载jar时出现了一些奇怪的行为,这是由maven3附带的OSX Lion更新引起的。我们的修复方法是重新部署受影响的项目。

You mentioned that you use maven 2.2.1 and I can only ask you to doublecheck, we had some strange behavior concerning downloading jars from internal repo that was caused by OSX Lion update that comes with maven3. Our fix was to redeploy affected project.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文