So I'm beginning to use the Java Properties class in order to set key-value pairs for my project. The way I'm designing my project is so that there are default properties which will be created using a config file as well as another config file for either overwriting or adding additional properties. The default config file will be in my Eclipse MainFramework project while the other config file will be in the local project where tests are stored.
MainFramework
Validation
TestProject1
TestProject2
In this example, MainFramework has the default config file and each TestProject may or may not have it's own local config file. Is there a way to have my desired functionality through Java's Properties class.
The java properties object is a Hashtable. If you read the properties for your main configuration file and then read a second properties file into the same object it will override the existing properties if they exist in both places, or add new ones if they don't already exist. Properties that are only found in the original file will remain as well.
How about using a 3rd party configuration library to achieve this?
Typesafe's config supports the usage of properties files, and can handle merging a global configuration with a subconfiguration, among many other features.
Apache commons configuration also supports property files as configuration sources and mechanisms for combining different sources.
I personally found Typesafe a bit easier to understand and use, but have a look at some examples to see what fits your style. They are both available through maven.
Related
I have an application that i have to deliver in a packaged JAR which is then run by the client in a complicated environment that makes editing env variables or JVM arguments very cumbersome (additionally client is not too technical). Currently we are using some external proeprty files for configuring the database and so on and this is going well so far.
I would like to allow the client to configure some aspects of Log4j2 using these properties files, i can see that Log4j2 allows multiple ways of performing property substitutions https://logging.apache.org/log4j/log4j-2.1/manual/configuration.html#PropertySubstitution
I can also see that it is possible to load property bundles but if i understand the docs correctly these bundles need to be loaded from classpath and i have not stumbled upon a possibility of define this properties file by giving its direct path (such as "load the properties file /tmp/myconfig.properties").
So ultimately - is it possible to use variables from an external .properties file that is NOT in classpath but in a specified filesystem location? Or maybe some other way exists to load this data from external file? (i already noted that using env variables or jvm arguments is out of the question in my case).
I have a file where we store common properties.
Multiple applications are using these when creating beans while every application has their own properties file also. Is there a way to source the common file from the application specific files when working with Java?
I tried sourcing the file and that does not work. Here is what I tried.
common.properties
password=abcd
application.properties
. /etc/application_dir/common.properties
application_log_file=/tmp/app.log
I want to read only application.properties in my code and get the properties from common.properties loaded also.
One way is to add common.properties to classpath for the beans also but I want to check if there is a cleaner option like above with only changes in the properties file.
Short answer: no you can't. But here are some ideas that might help you solve your problem.
A Java Properties object can be created with another one to supply defaults.
You can call load or loadFromXML multiple times on the same Properties object to "overlay" the contents of one properties file over another.
Non-XML properties files can have comments introduced by a #. So you could invent a special comment for "sourcing" a property; e.g.
#source /etc/application_dir/common.properties
and then parse your properties file(s) to pull out the "source" directives before loading the properties files.
XML properties files can have <comment> elements which could be used (abused) in the same way.
No ... sorry ... I'm not going to provide code samples.
I have a java project named dbstuff which reads properties from db.properties with getClass().getResourceAsStream("/db.properties"). The values are things like connection strings, etc. This dbstuff is used in various projects most of them are web.
I now have a dropwizard project (maven) which uses dbstuff.jar as a dependency, this project is compiled as a fat jar as described here, at the moment the dbstuff only read values from db.properties if the file is present in /src/main/resources, and when the package is created the db.properties becomes embedded in the jar.
What i want to achieve is to make db.properties external, so that i can have various db.properties (one for each environment) but only one dropwizard jar, is this possible?
thank you
You could pass in the path to the external db.properties file at runtime via a system property, e.g.:
java -jar myjar.jar -DdbConfig=/path/to/db.properties
Then in your code within dbstuff.jar you can load the properties file:
final String path = System.getProperty("dbConfig");
final Properties properties = Properties.load(new FileInputStream(path));
Alternatively, as you've mentioned you are using Dropwizard, within your configuration file (the yaml file or whatever you are using) have a property which specifies where the external db.properties file is, load the properties during server initialisation and then pass them on to whatever requires it in dbstuff.jar.
You could then take this a step further, forget about the db.properties file and have an entire section in your Dropwizard config that specifies all the properties, e.g.:
db:
url: jdbc://....
user: dbuser
# etc...
And then pass on what the objects in the dbstuff.jar need. See Dropwizard's configuration documentation for more information on how to do this.
I think you can create a configuration class in DropWizard and then use it to return the correct configuration for each environment - https://dropwizard.readthedocs.org/en/latest/manual/hibernate.html.
As for your question, if you have multiple resources on the same path, even if on different jars, there is no guarantee of which one Java will be using. When you add a file named db.properties to /src/main/resources, it becomes the resource "db.properties", and is read as such:
http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getResourceAsStream(java.lang.String)
I have several java projects which use hibernate to persist to a DB. At the moment, I have hibernate.properties file embedded in one persistence project.
However, I would like to be able to specify to have two different files one for prod and one for dev.
What is the best practise....should I embed the config files into my jars? How do I build my projects to use the correct properties with Maven?
Thanks.
You probably want to have the key database properties (name/user/password) set as properties at runtime either from a properties file that's itself specified as a property (the URL of the file can be specified as a property) or a set of properties (a property for each of name/user/password). The former is probably the preferred approach.
You could ask your system/database administrator type what they like :)
How can I load the configuration information for hibernate dynamically from a config file. Netbeans currently hard codes that information into an xml file that is then compiled into the jar. I'm a newbie to Java/Netbeans coming from PHP land and am use to a central bootstrap that pulls from a .ini or something similar, but netbeans tends to hardcode this information upon generation of the models,etc in an xml file that is then compiled in the jar. I'm looking for conventional methods of setting up configuration for various client machines using various database configurations. I don't want to have to compile the app on each machine it must be installed on.
The configuration file is read using the Configuration class. By default, it uses the hibernate.cfg.xml file found in the classpath, but you can use the configure method taking a file as parameter, and store the config file on the file system rather than in the jar.
You can also put the static mapping, which never changes between configs, in a file inside the jar, and put the varying config inside an external file. Look at the javadoc for Configuration to know how to add resources and config files to the configuration.