How to reference a system property within a user-defined .properties file? - java

I want to define a property for a working directory(say work.dir=/home/username/working-directory), for my production .properties file, without hard-coding the /home/username.
I want to reference the system property user.home in place on the hard-coded /home/username, to make work.dir more generic.
How do I reference the system property and concatenate it will other user-defined strings in a user-defined .properties?
Note: I don't want to access the user.home property in my java code, but from the .properties that I have defined. I want to be able to replace the value of the work.dir with different value for both my production and development(JUnit tests for example).

Get the property from the file, then replace supported macros.
String propertyValue = System.getProperty("work.dir");
String userHome = System.getProperty("user.home" );
String evaluatedPropertyValue = propertyValue.replace("$user.home", userHome );

You can manage your properties with Commons Configuration and use Variable Interpolation
If you are familiar with Ant or Maven, you have most certainly already encountered the variables (like ${token}) that are automatically expanded when the configuration file is loaded. Commons Configuration supports this feature as well[...]
That would allow a .properties file with
work.dir=${user.home}/working-directory

This feature is not available in java.util.Properties. But many libraries add variable substitution to properties.
Here an example of what you are trying to do using OWNER API library (see paragraph "importing properties"):
public interface SystemPropertiesExample extends Config {
#DefaultValue("Welcome: ${user.name}")
String welcomeString();
#DefaultValue("${TMPDIR}/tempFile.tmp")
File tempFile();
}
SystemPropertiesExample conf =
ConfigFactory.create(SystemPropertiesExample.class, System.getProperties(), System.getenv());
String welcome = conf.welcomeString();
File temp = conf.tempFile();

Related

spring boot - Can I read json files placed in src/main/resources by environment

I have a spring boot project with json files placed by environment under src/main/resources like this:
src/main/resources/dataFiles/dev - contains dev json files
src/main/resources/dataFiles/local - contains local json files, and so on.
I am trying to read the json file path depending on the active environment.
i.e. vaguely speaking, something like :
String path = "dataFiles/${spring.profiles.active}/someFile.json"
Is there a way to do this using spring profiles? How to ?
If I were to do this in an efficient way, what would it be ?
Thank you
In short, yes you can do this. In your component that you are doing the read, inject Environment
#Autowired
private Environment environment;
Then get the profiles with
String [] activeProfiles = environment.getActiveProfiles();
Keep in mind that many profiles may be active, so this returns an array. If you are certain that you will only set a single active profile, then you can the get the file as
String path = "dataFiles/" + activeProfiles[0] + "/someFile.json";
Probably a better approach would be to create property file for each of your profiles ad place the data path in the profile. e.g. for the local profile, create a application-local.yml file, and put a property in there called something like datapath, set to "datafiles/local/". In your component that reads the file, then you just have to inject this property
#Value("${datapath}")
String dataPath;
The read your file like
String path = dataPath + "someFile.json";

Unable to resolve ${file.separator} programmatically to read property path

I am trying to read a property which contains a file path including logged in user name in path as below.
test.file = ${file.separator}test${file.separator}${user.name}${file.separator}file.txt
I am able to read file with OS specific path (/ - unix or -windows) when I read the property using #Value annotation in a class and when used it in pom.xml as an argument..
When i read this as regular property from property file, spring is reading it as another string value which is expected.
But if i pass this value to File constructor, ${file.separator} doesn't get resolved..
what is the best way to represent file separator in a property file? I want to avoid .replace technique to replace a variable with File.separator in code.
If you are just looking for a file separator which is platform neutral then, we have been using / separator without any problem.
path=C:/Users/<user_name>/myconfig.properties
path=/Users/<user_name>/myconfig.properties
The following code always returns true on both systems.
finput = new File(prop.getProperty("path"));
System.out.println(finput.exists());

How to set the User Defined File Attribute in Java NIO for Unix OS?

I am trying to set user defined attribute to a file, for example, version=1 to the file foo.txt. So that I can retrieve the version attribute later.
I see Java NIO package provide such mechanism, I followed this document. However, I am trying to run this in my Unix operating system, it says null pointer exception, also I see that the blog says it is window-specific. So How can write attributes to file in Unix?
UserDefinedFileAttributeView userDefinedFAView = Files
.getFileAttributeView(path, UserDefinedFileAttributeView.class);
List<String> attributeList = userDefinedFAView.list();
System.out.println("User Defined Attribute List Size Before Adding: "
+ attributeList.size());
// set user define attribute
String attributeName = "version";
String attributeValue = "1";
userDefinedFAView.write(attributeName,
Charset.defaultCharset().encode(attributeValue));
The entire source code is below:
https://gist.github.com/ajayramesh23/e21d6159d8271fe0a4cfaf7209f6fb74
Reference blog for the source-code:
http://javapapers.com/java/file-attributes-using-java-nio/
Please provide the best way in Java 7 or above to set the file attributes.
Also, I see that Java Doc mentioned this below note:
Note:
In Linux, you might have to enable extended attributes for
user-defined attributes to work. If you receive an
UnsupportedOperationException when trying to access the user-defined
attribute view, you need to remount the file system. The following
command remounts the root partition with extended attributes for the
ext3 file system. If this command does not work for your flavor of
Linux, consult the documentation.
$ sudo mount -o remount,user_xattr /
If you want to make the change permanent, add an entry to /etc/fstab.
So How to set user-defined attributes without doing above note.

Is there default properties file to put configurations into?

Any default properties file which java can automatcially load?
The short answer is no.
The somewhat longer answer starts with a question itself: What should be configured by this file?
For the logging-API of java (java.util.logging) exists a standard-properties-file to configure it. Other frameworks may as well use standard-configuration files. But that always configure only stuff specific for this framework.
If you want to have persistent configuration, you probably want to use the Preference-API. That allows you to save configuration-data, that stays with the user or the JVM.
You can use your own default properties file. You can do it with just few lines.
There is also built in properties, however, these are no simpler, but they are standard.
IMHO Most of the time a plain Proeprties file is used.
This example from the tutorial. This is a more complex example, you can have just one properties file.
// create and load default properties
Properties defaultProps = new Properties();
FileInputStream in = new FileInputStream("defaultProperties");
defaultProps.load(in);
in.close();
// create application properties with default
Properties applicationProps = new Properties(defaultProps);
// now load properties from last invocation
in = new FileInputStream("appProperties");
applicationProps.load(in);
in.close();
You have to load your properties file yourself or pass arguments at command line.
There is a small library that you can use which will load properties automatically for you: Confucius.

Need help with making a settings file

I am trying to make an application launcher that has a settings file that will save 'names' for programs and the path to that program, and when you type the name in an input box it will run the program that name is assigned to.
Also if it the name entered is not known by the application (in the settings file) it will ask the user to add the path and will save that name with the user set path in the settings file.
What I need to know is the best way for me to do this and read/write the file, and the easiest way to organize the settings file to be interpreted.
Any suggestions?
You could use java.util.Properties - it stores key/value pairs in a textfile, and is fairly easy to instantiate. e.g:
Properties mySettings = new Properties();
mySettings.load(new FileInputStream("myapp.cfg"));
// getProperty() returns a String
filepath1 = mySettings.getProperty("filePath1");
Then you simply save your settings in myapp.cfg, either directly (it's a simple textfile with key=value pairs), or via mySettings.store(...). The contents of myapp.cfg will look something like this:
# comment and date added by the Properties object
filePath1=/usr/bin/share/filename
otherVar=52

Categories

Resources