1

Long story short, I'm making a java library that requires several 'config values'. Currently, I'm just using a config.properties file in the root directory and reading from it, but I don't see how that can work with a distributable jar file.

I've thought about making these config values parameters to a constructor of a class in the library, but there are too many values- it just doesn't seem like the correct way of doing things.

Essentially, I just need some way that a user of my library can just use the jar file, but also have the ability to change several configuration values that affect the function of the library.

If it makes any difference, I'm using maven to build my project.

Thanks in advance.

alex_joker
  • 73
  • 5
  • I would advice, to keep use a configuration file. But your library must be smart enough to find it first on multiple common places, like at user home and current directory, if the config file not found, look for one specific environment variable to point to the config file, and if the environment variable still not there, you can use the default config in your classpath. – Ferdinand Neman Aug 29 '15 at 03:39
  • This may be useful http://stackoverflow.com/questions/8775303/read-properties-file-outside-jar-file – Esteban Herrera Aug 29 '15 at 03:54
  • should I automate the creation of the config file in the root directory? It would seem silly to expect the user to create it themselves. – alex_joker Aug 29 '15 at 06:24

2 Answers2

1

(Assuming you are just working in JavaSE, as Java EE has other configuration mechanisms.)

A pattern is to create a singleton class in your jar that provides configuration to the other classes. Which is reads default values from the property file in the jar. Allow the caller of the jar to override properties by setting them as system properties.

In the java doc for Property class there is a constructor to provide defaults and overrides and get the 'net' properties.

Giving the caller the option specify a property file by giving a file path as a system property.

Log4j and java.util.logging work of like this. Reading through there config documentation will help explain.

Chris
  • 194
  • 6
0

I will split your question into two parts and then answer each part separately.

I've thought about making these config values parameters to a constructor of a class in the library, but there are too many values- it just doesn't seem like the correct way of doing things.

For the part of your question I have quoted above, see the accepted answer (written by me) to the following StackOverflow question: How to handle large number of configuration parameters across a program conceptually?

Essentially, I just need some way that a user of my library can just use the jar file, but also have the ability to change several configuration values that affect the function of the library.

It sounds like your configuration file will contain N variables, and a user might want to customize the values of, say, just 2 or 3 of those variables. If N is relatively small, then it will probably be okay to use an either-or approach to configuration:

  • either the user provides a configuration file containing values for all N variables (the location of this file might be specified via, say, a system property, an environment variable, or a parameter to the constructor of your library);

  • or your library uses a "built-in" set of default configuration values, which I suggest you place in a properties file that you bundle into your library's jar file and then access by calling ClassLoader.getSystemResourceAsStream().

However, if N is large, then you might want your library to provide and semantics for configuration variables:

  • your library uses a "built-in" set of default configuration values, which I suggest you place in a properties file that you bundle into your library's jar file and then access by calling ClassLoader.getSystemResourceAsStream(). This provides default values for all N variables.

  • and your library loads an (optional) user-specified configuration file that might contain anywhere between 0 and N variables. The values of the user-specified configuration variables are used to override the built-in default values.

Obviously, you will need to implement the and logic within your library, but that is really just a SMOP (Simple Matter of Programming). Perhaps the simplest way is to iterate over the entries in the user-provided Properties object and copy them into the Properties object that contains the default values. In this way, the user-specified value will override default values.

Community
  • 1
  • 1
Ciaran McHale
  • 2,126
  • 14
  • 21