Summary
When trying XMLConfiguration configuration = new XMLConfiguration("config/config.xml"); only with commons-configuration 1.10 do I need to add additional settings (namely commons-collections no newer than 3.2.1 ) in my maven setup. Why is this and why does not maven just resolve all the necessary dependencies?
More details
I am trying to get commons-configuration to work. At first I wanted to use the latest version of 2.0-alpha2, which did not work fine, because I was not able to configure Maven to load the correct resources - but this is another story.
After I found out that version 1.10 is actually “one point ten” (and not “one point one zero”) and thus the last version of general configuration 1 (and covered in tutorials), I decided to give it a try instead of this.
For my maven dependencies (integrated in eclipse) I used:
<dependency> <groupId>commons-configuration</groupId> <artifactId>commons-configuration</artifactId> <version>1.10</version> </dependency>
However, when testing 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:
<?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 an 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)
At first I hoped that they (and not I, of course) simply messed up some maven dependencies, and since I would not have to worry about which version to use anyway anymore (I did not get 2.0 to work, remember?) I decided to go all the way to version 1.9, replacing the maven dependency:
<dependency> <groupId>commons-configuration</groupId> <artifactId>commons-configuration</artifactId> <version>1.9</version> </dependency>
This solution to the problem is pretty good, the test script is running:
property nestedproperty.arrayvalue nestedproperty.property
But when I tried to implement a similar example with the one indicated in the Very simple Apache-commons configuration example that raises NoClassDefFoundError and its subsequent question, I got the exact same error referenced, but a solution importing org.apache.commons.beanutils.PropertyUtils does not work as I am missing beanutils. So basically, by downgrading, I just switched from the missing collection error to the missing beanutils.
There is a description of dependencies where you can see which dependencies are used when you do something. I was a little surprised to learn that version 1.10 now uses other dependencies (namely CollectionUtils ) than 1.9 in the constructor call. Since the dependency problems in 1.10, as well as in version 1.9, I simply stuck to the newer version.
I found that CollectionUtils is in the following artifact (since I pointed out its maven repository there ):
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> <version>4.0</version> </dependency>
Unfortunately, one (not obvious to me at first) does not define the CollectionUtils class in the collections package, but in the collections4 package. This was outlined for this problem in the dependency overview, but they only mentioned possible problems with earlier versions ... It seemed to me that I did not think about it anymore, but just changed the dependency:
<dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2.1</version> </dependency>
I have everything to work (more or less, but the Exceptions I get now no longer depend 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 should I add dependencies myself? I thought the whole point of using maven is to avoid having to do such things, and from the point of view of javadocs and source files, it does a pretty good job.
I am currently convinced that dependencies are not included in the design hierarchy (is that so?), Possibly to avoid overhead. However, is there a way to either just get all the dependencies at once or even better to get all the dependencies that I need? And why is it designed this way?