Java – Apache Commons Configuration — Cannot load/use config files

apache-commonsconfigurationjava

I've been trying to configure a Java application (specifically my integration tests) with absolutely no success. I originally had a single XMLConfiguration which I could load and use without issue. My directory setup looks like:

  • src
    • test
      • java
        • mypackage
      • resources

Before, I had a file myconfig.xml in the resources directory. I was loading it it like so:

private static XMLConfiguration configuration = null;
public static void configure() {
    try {
        configuration = new XMLConfiguration("myconfig.xml");
    }
    catch (ConfigurationException e) {
        System.err.println(e);
    }
}

Now I'm trying to make it so that users can configure the application themselves by writing a configuration file in /etc or /home or whatever, so I made a new file in the same location called config-test.xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<configuration>
    <!-- Attempt to load configuration provided on the system -->
    <xml fileName="/etc/myconf/myconfig.xml" config-optional="true" />

    <!-- Load default configuration from the classpath -->
    <xml fileName="myconfig.xml" />
</configuration>

The file /etc/myconf/myconfig.xml does not exist, but that's the whole point of making it optional. I've tried a few different approaches to loading my configuration, including how the documentation does it: http://commons.apache.org/configuration/userguide/howto_configurationbuilder.html. What I have currently is the following:

private static CombinedConfiguration configuration = null;
public static void configure() {
    try {
        DefaultConfigurationBuilder builder = 
            new DefaultConfigurationBuilder("config-test.xml");
        configuration = builder.getConfiguration(true);
        System.err.println("Yay");
    }
    catch (ConfigurationException e) {
        System.err.println("Herp");
    }
    catch (Exception e) {
        System.err.println("Derp");
    }
}

When I run my integration tests, I see no Yay, I see no Herp and I see no Derp. If I place a println before I try to load things, it does print so configure is being called. The output I get from commons configuration amounts to:

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running TestSuite
13:36:57.752 [main] DEBUG o.a.c.c.ConfigurationUtils - ConfigurationUtils.locate(): base is null, name is config-test.xml
13:36:57.753 [main] DEBUG o.a.c.c.DefaultFileSystem - Could not locate file config-test.xml at null: no protocol: config-test.xml
13:36:57.756 [main] DEBUG o.a.c.c.ConfigurationUtils - Loading configuration from the context classpath (config-test.xml)
13:36:57.766 [main] DEBUG o.a.c.c.DefaultConfigurationBuilder - Creating configuration null with name null
13:36:57.795 [main] DEBUG o.a.c.c.ConfigurationUtils - ConfigurationUtils.locate(): base is null, name is config-test.xml
13:36:57.795 [main] DEBUG o.a.c.c.DefaultFileSystem - Could not locate file config-test.xml at null: no protocol: config-test.xml
13:36:57.796 [main] DEBUG o.a.c.c.ConfigurationUtils - Loading configuration from the context classpath (config-test.xml)
13:36:57.800 [main] DEBUG o.a.c.c.DefaultConfigurationBuilder - Creating configuration null with name null
Tests run: 56, Failures: 2, Errors: 0, Skipped: 16, Time elapsed: 2.589 sec <<< FAILURE!

Results :

Failed tests:   initialize(mypackage.ImportTestIT): org/apache/commons/beanutils/PropertyUtils
  initialize(mypackage.TransferTestIT): org/apache/commons/beanutils/PropertyUtils

Tests run: 56, Failures: 2, Errors: 0, Skipped: 16

Those initialize methods are just calling configure and then trying to get data from the configuration that is loaded. I've been working with this for a couple hours now and could really use another pair of eyes. Any ideas? Is there anything I could have changed that I'm not mentioning that would affect this? Thanks.

Edit #1 (1:58pm): After making sure beanutils were on the classpath, I now get a brutal explosion of stack trace that starts with

Running TestSuite
14:00:16.088 [main] DEBUG o.a.c.c.ConfigurationUtils - ConfigurationUtils.locate(): base is null, name is config-test.xml
14:00:16.089 [main] DEBUG o.a.c.c.DefaultFileSystem - Could not locate file config-test.xml at null: no protocol: config-test.xml
14:00:16.093 [main] DEBUG o.a.c.c.ConfigurationUtils - Loading configuration from the context classpath (config-test.xml)
14:00:16.103 [main] DEBUG o.a.c.c.DefaultConfigurationBuilder - Creating configuration null with name null
14:00:16.178 [main] DEBUG o.a.c.c.ConfigurationUtils - ConfigurationUtils.locate(): base is file:///home/pgarrity/projects/myproject/target/test-classes/config-test.xml, name is /etc/myconf/myproject/myconfig.xml
14:00:16.179 [main] DEBUG o.a.c.c.DefaultFileSystem - Could not locate file /etc/myconf/myproject/myconfig.xml at file:///home/pgarrity/projects/myproject/target/test-classes/config-test.xml: /etc/myconf/myproject/myconfig.xml (No such file or directory)
14:00:16.181 [main] DEBUG o.a.c.c.DefaultConfigurationBuilder - Load failed for optional configuration xml: Cannot locate configuration source /etc/myconf/myproject/myconfig.xml
14:00:16.185 [main] WARN  o.a.c.c.DefaultConfigurationBuilder - Internal error
org.apache.commons.configuration.ConfigurationException: Cannot locate configuration source /etc/myconf/myproject/myconfig.xml
at org.apache.commons.configuration.AbstractFileConfiguration.load(AbstractFileConfiguration.java:259) ~[commons-configuration-1.8.jar:1.8]
at org.apache.commons.configuration.AbstractFileConfiguration.load(AbstractFileConfiguration.java:238) ~[commons-configuration-1.8.jar:1.8]

And so on and so on… but I do see 'Yay' now. Now what I don't get is that it doesn't seem to be looking for my non-optional configuration source, or assuming it's in a location I never told it to look.

Edit #2:
I looked through my output a bit more and buried in the complaints from commons I found that it seemed to load the correct file eventually. I think I may have it working? Maybe my path to the properties change when I load it like this… I've got some stuff to try. Anyway, the problem that I asked about has been fixed. Thanks for the help.

Best Answer

You seem to be missing commons-beanutils on your classpath. Make sure that jar is there.

Related Topic