仅使用XMLConfiguration configuration = new XMLConfiguration("config/config.xml");
尝试commons-configuration 1.10
时,我需要在maven设置中添加更多依赖项(即commons-collections
而不是3.2.1
)。为什么会这样,为什么maven不能简单地解决所有需要的依赖?
我想让commons-configuration开始工作。首先,我想使用最新版本2.0-alpha2,因为我无法配置Maven来下载正确的资源,所以它完全不能正常工作 - 但这是另一个故事。
在我发现版本1.10实际上是“一点十”(而不是“一点一零”)并因此最新版本的commons-configuration 1(并且由教程涵盖)之后,我决定给它试一试。
对于我的maven依赖项(集成在eclipse中),我使用了:
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<version>1.10</version>
</dependency>
然而,在尝试这个例子时:
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();
}
}
}
使用以下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>
我收到了错误:
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)
我首先希望他们(当然不是我)只是搞砸了一些maven依赖项,因为我不打算再使用哪个版本(我没有得到2.0工作,还记得吗?)我决定去通过使用:
替换maven依赖关系到版本1.9<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<version>1.9</version>
</dependency>
这很好地解决了问题,测试用例正在运行:
property
nestedproperty.arrayvalue
nestedproperty.property
但是当我尝试实现与Very simple Apache-commons configuration example throws NoClassDefFoundError及其后续问题中引用的类似示例时,我得到了完全相同的错误,但是引入org.apache.commons.beanutils.PropertyUtils
的解决方案是不工作因为我错过了豆腐。所以基本上通过降级我只是从错过集合的错误切换到缺少beanutils。
有一个dependency overview,您可以在其中查看执行操作时使用的依赖项。我有点惊讶地发现版本1.10现在使用了其他依赖项(即CollectionUtils
)而不是构造函数调用中的1.9。由于在1.10和1.9中存在依赖性问题,我只是坚持使用较新的版本。
我发现CollectionUtils
位于以下工件中(正如我maven repository指出的那样):
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.0</version>
</dependency>
可悲的是,那个(一开始对我来说不明显)并没有在包CollectionUtils
中定义类collections
,而是在包collections4
中定义。它在依赖性概述上暗示了这个问题,但他们只提到了早期版本可能存在的问题......我似乎已经不再考虑它了,只是简单地将依赖关系改为:
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
在使用这些依赖项后,我得到了所有工作(或多或少,但我现在得到的例外不再取决于缺少的类定义):
<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>
为什么我必须自己添加依赖项?我认为使用maven的重点是避免不得不做这些事情,就javadocs和源文件而言,它做得非常好。
到目前为止,我确信依赖关系不会被设计包含在层次结构中(是这样吗?),可能是为了避免开销。但是有没有办法可以简单地获取所有依赖项,甚至更好地获取我需要的所有依赖项?为什么这样设计?
答案 0 :(得分:11)
如果我们分析commons-configuration的POM,我们会发现commons-collections
依赖是可选的:
<dependencies>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
<optional>true</optional>
</dependency>
...
此外,来自Maven文档:
如果用户想要使用与可选项相关的功能 依赖性,他们将不得不重新声明可选的依赖关系 他们自己的项目。
答案 1 :(得分:3)
此问题在Commons Configuration网站的Runtime dependencies页面上进行了解释。
从该页面引用:
在Maven POM中声明了很多依赖项。这些都是在编译期间所需要的。 在运行时,您只需要将依赖项添加到您正在使用的Commons Configuration软件包部分所需的类路径中。下表可帮助您确定必须包含哪些依赖项。您打算使用的组件。
其他答案解释了为什么这可以从Maven的角度来看。这个答案旨在为Commons配置人员提供各种防御。他们至少警告过你!
如果依赖项存在于其他Apache Commons组件上,他们会花时间测试各种版本,并在该页面底部发布了有关兼容性的信息。
答案 2 :(得分:1)