Java Properties - How to Create Dynamic Properties

Java: dynamic properties

Java Properties - how to create dynamic properties

What you would have seen would be an ant or maven filter.
It is possible to have variables set at build time using this.

What your are talking about doesn't occur in the resource loaders that would read the propery files with out code in place.

Additionally ofcourse if you are writing the java to read the property to implement pattern matching to support this.

No one bothers usually as it is easier to either do it at build time with filters and mvn or ant or just write the code not to need redundant configuration blocks that would benefit from dynamic content.

How to model an object with dynamic properties?

Even if you limited yourself to numeric properties, price is a different type of number from weight. Adding in string properties makes it more difficult to manage just one property class.

One answer is to have more than one property class. One for strings, one for integer numbers, and one for prices. A reason to separate prices from other numbers is that you want to be careful when adding and subtracting prices.

How To: Dynamically-defined properties in Java

Keep going with the .properties and load the file as a resource.

If it is in the classpath it would be found.

What I use, because it is much easier to me is a resource bundle instead.

edit

If the file is in your classpath you can loaded it either as a resource with: Some.class.loadResource(...) or what I do is use a ResourceBundle which does basically the same.

For instance if I have:

import java.util.ResourceBundle;

public class ResourceBundleTest {
public static void main( String [] args ) {
ResourceBundle bundle = ResourceBundle.getBundle("connection");
for( String key: bundle.keySet() ){
System.out.printf("bundle[%s]=%s%n",key, bundle.getString(key));
}
}
}

I can load that file if is in the class path. The property is outside, in "some/nested/dir"

$ls -l some/nested/dir/
total 8
-rw-r--r-- 1 oscarreyes staff 35 Jun 25 12:06 connection.properties
$cat some/nested/dir/connection.properties
name=Oscar
lastName=Reyes
age=0x1F

If I run it without adding that directory to my classpath it wont work:

$java ResourceBundleTest 
Exception in thread "main" java.util.MissingResourceException: Can't find bundle for base name connection, locale es_ES
at java.ut...ceBundle.java:1427)
at java.ut...urceBundle.java:1250)
at java.ut...ceBundle.java:705)
at Resourc...st.java:6)

But if I add the directory to my classpath, then the file will be found easily.

$java -cp some/nested/dir/:.  ResourceBundleTest 
bundle[lastName]=Reyes
bundle[age]=0x1F
bundle[name]=Oscar
$

In a similar fashion, you can have a .jar file, and put your .properties file wherever you want, you just have to include it in your classpath.

The equivalent using properties would be:

import java.util.Properties;

public class LoadProperties {
public static void main( String [] args ) throws java.io.IOException {
Properties properties = new Properties();
properties.load( LoadProperties.class.getResourceAsStream("connection.properties"));
properties.list( System.out );
}
}

But for some reason I prefer the resource bundle.

Dynamically set all properties files at runtime:

The properties added to the properties file are read when the app starts. Once it is up and running, changes to the properties file wouldn't reflect unless you restart the app. There is no way to dynamically update the properties file to reflect in the app.

The only way to dynamically update properties of an app would be to use something like a configuration server. Read about it here.

https://spring.io/guides/gs/centralized-configuration/

how to configure 'dynamic key' in properties file loaded using @PropertySource in Spring

You need to use MessageSource, which is an interface for resolving messages. ResourceBundleMessageSource is MessageSource implementation which can read from properties file.

You'll need to configure it (I have not tried to compile the source)

@Bean
MessageSource messageSource() {
ResourceBundleMessageSource source=new ResourceBundleMessageSource();
source.setBasenames("messages");
return source;
}

You'll have to wire it and in the code you would call:

String errorText1 = source.getMessage("empty.error", "name", Locale.US);

and in your messages file you would have:

empty.error = {0} is empty

As a bonus, your app will be ready for internalization.



Related Topics



Leave a reply



Submit