3

I try to simple usage of simple Apache Commons Configuration2 loading configuration from a properties file. Here is my dependency:

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-configuration2</artifactId>
        <version>2.1</version>
    </dependency>

I try to start my web application and get this:

java.lang.ClassNotFoundException: org.apache.commons.beanutils.DynaBean
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1285)
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1119)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at com.sun.proxy.$Proxy21.<clinit>(Unknown Source)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:739)
    at org.apache.commons.configuration2.builder.fluent.Parameters.createParametersProxy(Parameters.java:294)
    at org.apache.commons.configuration2.builder.fluent.Parameters.properties(Parameters.java:245)

Lovely. Since when can't we use Maven to get dependencies automatically? I look at the commons-configuration2 POM on Maven Central and see that commons-beanutil is declared as optional.

<dependency>
  <groupId>commons-beanutils</groupId>
  <artifactId>commons-beanutils</artifactId>
  <version>1.9.2</version>
  <optional>true</optional>
</dependency>

Why is it declared as "optional" when obviously I need it?

Garret Wilson
  • 18,219
  • 30
  • 144
  • 272

1 Answers1

3

This dependency is marked as optional because it is only required for some non central features of the library, which means you can still use most of the library without having this dependency installed.

As per the documentation: Runtime dependencies for Commons Configuration 2.0

Commons Configuration 2.0 requires Java 6 or later.

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:

Considering tables are not easily included in a SO answer, I'll just list the features from commons-configuration-2 which requires you to include beanutils:

  • Configuration builders
  • ConfigurationDynaBean

In your case, based on the stack trace you provided, you are using a configuration builder and thus need to manually included the beanutils dependency in your pom.

Gorkk
  • 1,047
  • 11
  • 25
  • 3
    But doesn't the [documentation say](https://commons.apache.org/proper/commons-configuration/userguide/howto_builders.html#Configuration_Builders) that "The recommended way is to use a _configuration builder_"? (Emphasis in the original.) So basically you're saying that this dependency is optional --- unless I use the library in the recommended way? Don't you see a bit of a conflict there? – Garret Wilson Nov 30 '16 at 17:19
  • It sure would be clearer and more straightforward if the documentation at least mentioned next to this recommendation that this implies adding the optional dependency. For using the optional maven dependency, I guess the Apache Commons team wanted to avoid forcing loading unnecessary dependencies for projects trying to minimise dependencies used. – Gorkk Dec 01 '16 at 08:21
  • 2
    An optional dependency that's required just to build parameters (eg specify a file to load config from), a pattern that is used throughout examples, and that results in obscure ClassNotFound exceptions if you don't explicitly add it, which no one would think to do until they hit the exception and google? That's an *awful* API. – Adrian Baker Jan 15 '18 at 06:35
  • 1
    yeah people use modules for that! – saiedmomen Nov 03 '18 at 09:20
  • This is why people use maven, to allow them to separate their API, having the builder in another module that has "beanutils" as a dependency ! – Mansour Jul 15 '19 at 01:04