java 为什么 Maven 不解决 commons-configuration 的所有依赖项?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28692844/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 14:00:25  来源:igfitidea点击:

Why is Maven not resolving all dependencies for commons-configuration?

javamavenapache-commons-config

提问by Sebastian H?ffner

Summary

概括

When trying XMLConfiguration configuration = new XMLConfiguration("config/config.xml");with only commons-configuration 1.10I need to add more depencies (namely commons-collectionsnot newer than 3.2.1) to my maven setup. Why is that so and why doesn't maven simply resolve all needed dependencies?

XMLConfiguration configuration = new XMLConfiguration("config/config.xml");仅尝试时,commons-configuration 1.10我需要向我的 Maven 设置添加更多依赖项(即commons-collections不比 更新3.2.1)。为什么会这样,为什么 maven 不简单地解决所有需要的依赖项?

Details

细节

I am trying to get commons-configurationto work. First I wanted to use the latest version, 2.0-alpha2, which didn't work well at all since I was unable to configure Maven to download the correct ressources - but that is another story.

我正在尝试让commons-configuration工作。首先,我想使用最新版本 2.0-alpha2,它根本无法正常工作,因为我无法配置 Maven 以下载正确的资源 - 但那是另一回事了。

After I found out that version 1.10 is in fact "one point ten" (not "one point one zero") and thus the latest version of commons-configuration 1 (and covered by the tutorials), I decided to give it a try instead.

在我发现 1.10 版本实际上是“一点十”(而不是“一点一零”)以及最新版本的 commons-configuration 1(并包含在教程中)之后,我决定尝试一下.

For my maven dependencies (integrated in eclipse) I used:

对于我的 maven 依赖项(集成在 eclipse 中),我使用了:

<dependency>
    <groupId>commons-configuration</groupId>
    <artifactId>commons-configuration</artifactId>
    <version>1.10</version>
</dependency>

However, when trying out this example:

但是,在尝试此示例时:

package main;

import java.util.Iterator;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;

public class ConfigurationTest {
    public static void main(String... args) {
        try {
            XMLConfiguration configuration = 
                    new XMLConfiguration("config/config.xml");
            Iterator<String> iterator = configuration.getKeys();
            while (iterator.hasNext()) {
                System.out.println(iterator.next());
            }
        } catch (ConfigurationException e) {
            e.printStackTrace();
        }
    }
}

with the following config.xml:

使用以下 config.xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<configuration>
  <property>value</property>
  <nestedproperty>
    <arrayvalue>0,1,2,3,4</arrayvalue>
    <property>anothervalue</property>
  </nestedproperty>
</configuration>

I got the error:

我收到错误:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/collections/CollectionUtils
    at org.apache.commons.configuration.XMLConfiguration.constructHierarchy(XMLConfiguration.java:640)
    at org.apache.commons.configuration.XMLConfiguration.initProperties(XMLConfiguration.java:596)
    at org.apache.commons.configuration.XMLConfiguration.load(XMLConfiguration.java:1009)
    at org.apache.commons.configuration.XMLConfiguration.load(XMLConfiguration.java:972)
    at org.apache.commons.configuration.XMLConfiguration$XMLFileConfigurationDelegate.load(XMLConfiguration.java:1647)
    at org.apache.commons.configuration.AbstractFileConfiguration.load(AbstractFileConfiguration.java:324)
    at org.apache.commons.configuration.AbstractFileConfiguration.load(AbstractFileConfiguration.java:261)
    at org.apache.commons.configuration.AbstractFileConfiguration.load(AbstractFileConfiguration.java:238)
    at org.apache.commons.configuration.AbstractHierarchicalFileConfiguration.load(AbstractHierarchicalFileConfiguration.java:184)
    at org.apache.commons.configuration.AbstractHierarchicalFileConfiguration.<init>(AbstractHierarchicalFileConfiguration.java:95)
    at org.apache.commons.configuration.XMLConfiguration.<init>(XMLConfiguration.java:261)
    at main.ConfigurationTest.main(ConfigurationTest.java:12)

I first hoped they (not me, of course) just screwed up some maven dependencies and since I wouldn't bother which version to use anyway anymore (I didn't get 2.0 to work, remember?) I decided to go down to version 1.9 by replacing the maven dependency with:

我首先希望他们(当然不是我)只是搞砸了一些 maven 依赖项,因为我不会再费心使用哪个版本了(我没有让 2.0 工作,记得吗?)我决定转到版本1.9 通过将 maven 依赖替换为:

<dependency>
    <groupId>commons-configuration</groupId>
    <artifactId>commons-configuration</artifactId>
    <version>1.9</version>
</dependency>

That solved the problem pretty well, the test case is running:

这很好地解决了问题,测试用例正在运行:

property
nestedproperty.arrayvalue
nestedproperty.property

But when I tried to implement a similar example to the one referenced in Very simple Apache-commons configuration example throws NoClassDefFoundErrorand its follow-up question I got the exact same error which is referenced there - but the solution, importing org.apache.commons.beanutils.PropertyUtilsis not working as I am missing the beanutils. So basically by downgrading I just switched from the error of missing the collections to missing beanutils.

但是,当我尝试实现与非常简单的 Apache-commons 配置示例引发 NoClassDefFoundError及其后续问题中引用的示例类似的示例时,我得到了在那里引用的完全相同的错误 - 但解决方案,导入org.apache.commons.beanutils.PropertyUtils无法正常工作我想念 beanutils。所以基本上通过降级,我只是从缺少集合的错误切换到缺少 beanutils。

There is a dependency overviewwhere you can see which dependencies are used when you do what. I was a bit suprised to learn that version 1.10 now used other dependencies (namely the CollectionUtils) than 1.9 did in the constructor call. Since there were dependency problems in 1.10 as well as in 1.9 I just sticked to the newer version.

有一个依赖项概述,您可以在其中查看执行操作时使用了哪些依赖项。我有点惊讶地发现 1.10 版现在CollectionUtils在构造函数调用中使用了其他依赖项(即),而不是 1.9 版。由于 1.10 和 1.9 中存在依赖性问题,我只是坚持使用较新的版本。

I found the CollectionUtilslocated in the following artifact (as I was pointed there by its maven repository):

我发现CollectionUtils位于以下工件中(正如我在其maven 存储库中指出的那样):

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.0</version>
</dependency>

Sadly that one (not obvious to me at first) doesn't define the class CollectionUtilsin the package collections, but in the package collections4. It was hinted at this problem on the dependency overview, but they only mentioned possible problems with earlier versions... I appeared to be at a point of not thinking much about it anymore but simply changed the dependency to:

可悲的是,那个(一开始对我来说并不明显)没有CollectionUtils在包中定义类collections,而是在包中定义类collections4。在依赖概述中暗示了这个问题,但他们只提到了早期版本可能存在的问题......我似乎不再考虑它了,只是简单地将依赖更改为:

<dependency>
    <groupId>commons-collections</groupId>
    <artifactId>commons-collections</artifactId>
    <version>3.2.1</version>
</dependency>

I got everything to work (more or less, but the Exceptions I get now are not anymore depending on missing class definitions) after using these dependencies:

使用这些依赖项后,我让一切正常工作(或多或少,但我现在得到的异常不再依赖于缺少的类定义):

<dependencies>
    <dependency>
        <groupId>commons-configuration</groupId>
        <artifactId>commons-configuration</artifactId>
        <version>1.10</version>
    </dependency>
    <dependency>
        <groupId>commons-collections</groupId>
        <artifactId>commons-collections</artifactId>
        <version>3.2.1</version>
    </dependency>
    <dependency>
        <groupId>commons-beanutils</groupId>
        <artifactId>commons-beanutils</artifactId>
        <version>1.9.2</version>
    </dependency>
</dependencies>

Why do I have to add the dependencies myself? I thought the whole point in using maven is to avoid having to do such things and in terms of javadocs and source files it does a pretty good job.

为什么我必须自己添加依赖项?我认为使用 maven 的全部意义在于避免必须做这样的事情,并且在 javadocs 和源文件方面它做得很好。

By now I am convinced that the dependencies are not included in the hierarchy by design (is that so?), probably to avoid overhead. However is there a way to either simply get all dependencies at once or even better to get all dependencies I need? And why is it designed this way?

到目前为止,我确信依赖项不按设计包含在层次结构中(是这样吗?),可能是为了避免开销。但是,有没有一种方法可以一次简单地获取所有依赖项,或者甚至更好地获取我需要的所有依赖项?为什么它是这样设计的?

回答by Evgeniy Dorofeev

If we analyse commons-configuration's POM we see that the commons-collectionsdependency is optional:

如果我们分析 commons-configuration 的 POM,我们会看到commons-collections依赖项是可选的:

  <dependencies>
    <dependency>
      <groupId>commons-collections</groupId>
      <artifactId>commons-collections</artifactId>
      <version>3.2.1</version>
      <optional>true</optional>
    </dependency>
    ...

Furthermore, from the Maven docs:

此外,来自 Maven 文档:

If a user wants to use functionality related to an optional dependency, they will have to redeclare that optional dependency in their own project.

如果用户想要使用与可选依赖项相关的功能,他们将不得不在自己的项目中重新声明该可选依赖项。

回答by Duncan Jones

This issue is explained on the Runtime dependenciespage of the Commons Configuration website.

此问题在 Commons Configuration 网站的运行时依赖项页面上进行了解释。

Quoting from that page:

从该页面引用:

A lot of dependencies are declared in the Maven POM. These are all needed during compile time. On runtime however you only need to add the dependencies to your classpath that are required by the parts of the Commons Configuration package you are using.The following table helps you to determine which dependencies you have to include based on the components you intend to use.

在 Maven POM 中声明了很多依赖项。这些都是编译时需要的。但是,在运行时,您只需要将依赖项添加到您正在使用的 Commons 配置包的部分所需的类路径中。下表可帮助您根据要使用的组件确定必须包含哪些依赖项。

The other answers explain why this works from a Maven perspective. This answer is intended to provide a defence, of sorts, to the Commons Configuration folks. They did at least warn you!

其他答案从 Maven 的角度解释了为什么这样做。这个答案旨在为共享配置人员提供某种形式的防御。他们至少警告过你!

In cases where the dependencies are on other Apache Commons components, they've taken the time to test with a variety of versions and have posted information on compatibility at the bottom of that page.

如果依赖项依赖于其他 Apache Commons 组件,他们会花时间用各种版本进行测试,并在该页面底部发布了有关兼容性的信息。

回答by Jan

Maven tries to resolve all necessary dependencies for a library you're using in your pom. Well sometimes you have some dependencies which are only necessary for some specific features and you don't want to force the user of your dependency to download it if he doesn't use it. Then you're declaring your dependency as optional. This happened with commons-collectionswithin commons-configuration. See commons-configuration-pom here

Maven 尝试解决您在 pom 中使用的库的所有必要依赖项。好吧,有时您有一些依赖项,这些依赖项仅对某些特定功能是必需的,并且您不想强迫依赖项的用户在他不使用它时下载它。然后你将你的依赖声明为optional。这发生commons-collectionscommons-configuration. 在这里看到commons-configuration-pom