Reputation: 5931
I am working on a product suite which has 4 products. Right now, all of the configuration data is either in the XML or properties files.This approach is not maintainable as we have to manage different configuration file for different environment(for e.g. Production, Development etc).
So, what is the best way to handle configuration data?
Also, can we modularize this into a separate module? So that all products can use this module. We don't want to use the property files. I am looking for a solution in which we can move all of the configuration specific code as a new configuration module and persist all the configuration data in database.
Upvotes: 32
Views: 44751
Reputation: 1968
Modern solution in 2023:
Your very best bet is to create Spring Boot Java application and define absolutely all of your properties in the application.properties
or application.yml
file.
Pros:
Upvotes: 0
Reputation: 1659
Environment variables are just about the easiest way to go. Set them as you would any other time, access them w/ System.getenv("...")
Upvotes: 0
Reputation: 597362
Using commons-configuration you have a unified API for accessing the properties, no matter how they are represented - .properties, xml, JNDI, etc. For example:
config.properties
:
jdbcHost=192.168.12.35
jdbcUsername=dbuser
jdbcPassword=pass
config.xml
:
<config>
<jdbcHost>192.168.12.35</jdbcHost>
<jdbcUsername>dbuser</jdbcUsername>
<jdbcPassword>pass</jdbcPassword>
</config>
in both cases they will be accessible with something like:
String host = config.getString("jdbcHost");
Upvotes: 22
Reputation: 131
There are plenty of different strategies. All of them are good and depends on what suit you best.
Upvotes: 2
Reputation: 10173
If your applications work with a database, you can create a "configuration" table as follows:
create table configuration (mode char(3), key varchar(255), value varchar(1023));
You would initialize it using an init script, say init.sql with contents along the lines of:
insert into configuration values ('pro', 'param1', 'value1'); -- production
insert into configuration values ('dev', 'param1', 'value1'); -- development
insert into configuration values ('tst', 'param1', 'value1'); -- testing
...
The benefits of this approach are as follows:
Upvotes: 5
Reputation: 514
For all of our environments, configuration data lives on the target machines in the form of properties files. We use PropertyPlaceholderconfigurer from SpringFramework to bind these properties to our apps to keep things portable accross environments.
For example, as long as I know that /etc/myapp/database.properties will be present on whatever machine my app will be running on, then in my spring configuration, I just need something like so:
<bean id="myPropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>/etc/myapp/database.properties</value>
</list>
</property>
</bean>
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://${db.host}:3306/${db.name}" />
<property name="username" value="${db.user}" />
<property name="password" value="${db.pass}" />
</bean>
There are a bunch of options for that Spring class about where properties files can live. You can even make them substitutions and pass them in as environment variables:
<bean id="myPropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="searchSystemEnvironment" value="true" />
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="locations">
<list>
<value>${database.configuration.file.url}</value>
</list>
</property>
</bean>
And in bash_profile (or whatever): export JAVA_OPTS="-Ddatabase.configuration.file.url=file:///etc/myapp/database.properties"
Or just the same -D option passed in when you call "java" depending on what you are doing.
FWIW, we maintain our properties files separately as RPMs.
Upvotes: 4
Reputation: 33227
You're almost there... I would keep your same approach and pull in the correct configuration file for the instance of the application that is running by a method similar to either of the following:
Name all of your configuration files differently and have your application pull them in by some unique criteria (username, hostname, etc.):
Keep them outside the codebase in a location based on an environment variable that the application assumes exists:
I've even used a combination of these approaches on the same project (#1 for build process configurations and #2 for runtime configurations).
Upvotes: 12