Confused about java properties file location - java

I have simple java project with structure:
package com.abc:
a.java
b.java
c.properties
I have database configuration parameters configured in c.properties file.
Inside a.java and b.java, I am loading properties file using:
Properties p = new Properties();
InputStream in = this.getClass().getResourceAsStream("c.properties");
p.load(in);
This works fine. But the main question is, once I prepare executable jar by exporting this code, properties file also gets packaged in jar file. If someone else wants to modify properties file for different database configuration, how can he do it?
Do I have to store properties file in some fixed location in local machine. e.g. "c:/". Then give jar along with properties file to the other person. Then he needs to copy properties file inside C:/ location?
Also one more question, how can i make this location generic for windows and linux machine?

The typical way of handling this is to load the base properties from your embedded file, and allow users of the application to specify an additional file with overrides. Some pseudocode:
Properties p = new Properties();
InputStream in = this.getClass().getResourceAsStream("c.properties");
p.load(in);
String externalFileName = System.getProperty("app.properties");
InputStream fin = new FileInputStream(new File(externalFileName));
p.load(fin);
Your program would be invoked similar to this:
java -jar app.jar -Dapp.properties="/path/to/custom/app.properties"

First keep the default properties in your properties file, which gets packed into the jar. When the application starts try reading a same named properties file from some default location in filesystem, preferrable the user's home folder which you can obtain by System.getProperty("user.home");. If the file exists at the filesystem load it, if it doesn't exist then load your packed properties file and write a copy to the filesystem.
So if your properties file name is myprops.properties, initially only your jar file will contain it. When the application starts up it will check whether /home/xyz/myprops.properties file exists. Since it doesn't, it will read the packed properties file and write a copy to /home/xyz/myprops.properties file. From next time onwards, it will read from /home/xyz/myprops.properties.

Why not pass the location of the properties file as a command line argument (following a flag)? if it's not present, then use the default one in the jar file.

You're loading the properties file from the class path. I'd suggest something like this:
Properties location

Related

Override properties file from jar

I have a properties file in one of the .jar of my maven dependencies. I would like to override the values in my application so I created a file with the same name and the same package, but the values from the jar file are still being used. If I delete the properties file from the jar, the values of the file in my application are used. How can I always use the properties from my application instead of the .jar ?
As long as code takes your property file from class path it depends how your class path configured.
If you externalized your file out of any jar files - Try to put path to directory where your actual file located upfront of any other jar files in your java command -cp parameter.
If you keep your file inside your own jar file, in classpath - your jar file must be before that dependency jar file with default properties file.
Still those are not good solutions (sometime it is hard to control which path JVM will use first).
So, try to find documentation about your dependency jar - it may have a property to point from where and which properties file to use.
You can use Maven Resource Plugin and parametrize your configuration file so you can pass the parameters as arguments through command line
Use the properties resource in the jar as template, initial file for the properties file you will use:
Path propertiesFile = Paths.get(System.getProperty("user.home"),
".myapp/config.properties");
Files.createDirectories(propertiesFile.getParent());
if (!Files.exists(propertiesFile)) {
Files.copy(getResourceAsStrem("/config.properties"), propertiesFile);
}
Properties props = new Properties();
props.load(new FileInputStream(propertiesFile.toString());
How about this ?
rename the properties file with overridden values,
like this _override.properties (if the actual file is
called original.properties.
Now, in your code, read a system property, called 'toOverrideProps', if true, to load the overridden properties file
when running your program, you can set this property using the -Dprop=value method
This way, you have a choice on startup, to use the actual properties file or the overridden one, without conflict.

read a path from a config.properties file

I have a file named config.properties in Eclipse with the following content:
PATH_TO_A_FILE=a.txt
PATH_TO_B_FILE=b.txt
PATH_TO_C_FILE=c.txt
In my code, I need to use these properties like this:
conf.put("PATH_TO_B_FILE", properties.getProperty("PATH_TO_B_FILE"));
which files A.txt and B.txt are in the same path of the config.properties in the workspace folder
What I should do read those paths from my config.properties file?
Also: should I add a path before b.txt?
Should I write it as /home/user/workspace/b.txt or .home.user.Dersktop.b.txt?
Suppose that you have a file with path /home/user/Desktop/my.conf that contains properties, then you can load these properties in a Properties object like this:
Properties properties = new Properties();
InputStream input = new FileInputStream("/home/user/Desktop/my.conf");
properties.load(input);
Now you can get the properties like this:
String pathToA = properies.get("PATH_TO_A_FILE");
Obviously, you shouldn't put that properties file my.conf on your desktop. Are you creating a web app? In that case, you can ship the properties file with your jar. Files can be read from a jar using an InputStream, but that's a different question ;-)
Whether or not you should add a full path in the properties file also depends on the context of your application. In a server environment, you may not have a /home/user/Desktop directory. If you want an answer to that second question, you should clarify the context of your question. For instance: is your application a desktop or server application? what is the working directory of your application?

How to maintain a configuration file in java application project like a configuration file in C# application?

In C#,when I want to create a configuration file, it's so easy,just right click the mouse and add a new configuration file, this file will be added into the solution and it's so easy to maintain.
But in java, I don't know what method is standard. I see some people use the properites file.If this is the most popular method, can some one tell me where to place this file? I saw some guy put it in the src folder, others put it in an external folder.
Can you tell me which is the standard? And what is the best practice to maintain a configuration.
I don't know if this is the "standard" way but I think it's the easiest. If you place your properties file in your project's root folder
- project
- config.properties
- src
- main
- ...
- test
When you create a File instance in Java and specify a relative filename, then the name is resolved against the directory that Java was launched from
e.g. if you launch java in your command prompt as follows:
cd C:\Users\Tom\example-project
java example-project
and this is your code:
File file = new File("tom.txt");
then the file variable will be resolved to the abolsute path: C:\Users\Tom\example-project\tom.txt
When you Run a project through Eclipse, Eclipse launches java from the root directory of the project, meaning that if you put your config file in the project's root folder then
File file = new File("name-of-config-file.properties");
will resolve to the correct config file on your system.
This has an added benefit if you create a runnable JAR, as you can just place your config file in the same directory as your JAR and the code will continue to work (the config file location will be resolved relative to the JAR).
If you put your config file in /src folder then you need to have separate code for when running from Eclipse and when running as a JAR
With regards to sample code:
//Read properties from disk
File propertiesFile = new File("config.properties");
FileReader reader = new FileReader(propertiesFile);
Properties props = new Properties();
props.load(reader);
//Set and get properties
props.setProperty("NewProperty", "value");
String propValue = props.getProperty("propToGet");
//Write properties to disk
FileWriter writer = new FileWriter(propertiesFile);
props.store(writer, "Added x properties");
Configuration files are used to store,read write user settings.
I think for web apps you can use web.xml.And for other you should use Properties class to read and write settings.
As for where to place it,If you dont specify path it is stored in your root folder other than that you have to provide explicit path.

Reference .properties file in classpath

I want to know how to reference a .properties file in classpath? I have a jar file (contain a webservice in java), I have insert my connection details in a .properties file. I want to put this file outside the jar file in case the connection details needs to be changed. How do i reference this .properties file in my jar?
I will run my jar file using batch file.
You might have to add the staticresources directory in your buildpath, but upon doing so it shouldn't be difficult for you to implement something like
properties.load(this.getClass().getResourceAsStream("somefile.properties"));
to reference your .properties file.
I would recommend looking over this from the Java docs for more information on accessing resources if this is unfamiliar territory.
You can add a directory to the classpath using java -cp /path/to/file in your java call in your batch file.
When your properties file is in your classpath, you should be able to access it using something like:
Properties prop = new Properties();
InputStream is = getClass().getClassLoader().getResourceAsStream("connectionDetails.properties");
prop.load(is);

How do I store and retrieve Properties inside Runnable JAR?

I'm trying to use Java class Properties for saving the settings for my application between executions. Afterwards I would like to export my application into runnable JAR file and keep everything needed in this one file to provide portability. So my application has to find the properties file, load it and then save new settings into it on exit.
The loading works fine:
Properties prop = new Properties().load(this.getClass().getResourceAsStream("properties.cfg"));
But for storing I need to find the same file and overwrite it. The method Properties.store() needs an OutputStream but getResourceAsStream returns an InputStream therefore I cannot find the file and access it.
It should be always located with the *.class file. I found many solutions that work before exporting into JAR but none that would work after exporting. Thanks for any suggestions.
You can't rewrite your jar (or rather, it's complicated and not a good idea).
A preferable solution would be to read the properties from:
a directory on your machine
the .jar file
Initially location 1 wouldn't have a property file and you'd fall back to your .jar file. When you write the properties you'd write them to the nominated directory, and then on the next read you'd read your properties from this location. This would survive restarts etc.
Note that libraries such as Apache Commons Configuration automatically support this tiered properties location mechanism and may save you some time/grief in writing your own solution.
take spring's IO infrastructure (ClasspathResource)
try {
ClassPathResource r = new ClassPathResource("bdd.properties");
Properties properties = new Properties();
properties.load(r.getInputStream());
} catch (IOException e) {
Throwables.propagate(e);
}
this is real simplification.
For this kind of scenario the best approach is to add the properties file to the classpath and load it using something like ResourceBundle.
private static ResourceBundle _properties = ResourceBundle.getBundle("sample.properties");
String sampleProperty = _properties.getString(propertyKey);
How to execute :
Suppose your jar file is MyJar.jar and property file is called sample.properties
then u should write a batch or sh file around it
eg: run.sh
java -cp MyJar.jar:conf "Class with main Method"

Categories

Resources