I have something like:
Properties props = new Properties();
// This type of key-value property is in several code lines
props.put("mail.transport.protocol", settings.getSmtpProtocol());
In my code, props is accessed at several places. And each time, I need to access some property by its string key. Recently, I made a small code change in one of these key strings, and the key mismatch created a havoc.
What should be the correct design to avoid this kind of problem in my code base, assuming it increases in size and complexity in near future? Following options that I can think of, but not sure what should be the best way:
Instead of writing keys as bare strings like "mail.transport.protocol", "mail.smtp.host", "mail.smtp.port" at several places in code, have them stored in a class? And unit test whether appropriate class variable is added into properties or not?
Should I refactor props to another class [with only my required properties] alltogether, given props is get/set in many code lines already?
Have key strings as it is in props and get the "keys" as unit tested? But, keys are written several times as bare strings.
Create a separate properties file. say mail.properties.
This file holds all key value pairs. In future if somebody wants to change any of the properties, he can just update this properties file instead of changing java classes.
Then create a Java class to load all of these properties and create public static constants for each of the properties in that class.
Use the above constants where ever you want to use them.
Related
For debugging, I want a way to discover, for a running JVM at a given moment, all the names and all the values of all the properties maintained in the java.security.Security class.
I've learned a few things from studying the API specification and the Java Cryptography Architecture Guide...
If I know the name of a property, I can find its current value using getProperty. But I don't know how to discover all the names.
Initial settings for the properties can be made in configuration files, but settings can later be added and changed dynamically, using setProperty. I'm interested in the current settings, which would not necessarily be the initial settings.
Thank you for any guidance!
setProperty and getProperty both manipulate the internal props field. You could access it using reflection API. Use this strictly as throwaway code for debugging! Should never get into production code.
Field f = Security.class.getDeclaredField("props");
f.setAccessible(true);
Properties allProps = (Properties) f.get(null); // Static field, so null object.
System.out.println(allProps); //Or iterate over elements()/propertyNames() and print them individually
use Security class :
String certDisabled = Security.getProperty("jdk.certpath.disabledAlgorithms");
String tlsDisabled= Security.getProperty("jdk.tls.disabledAlgorithms");
I have an XML file, which contains rules for code analyzer (to search vulnerabilities). So, it has very different rules like parameter, parameter count, any parameter type, const value and etc for method call (to detect specific calls), rules to detect some imports, inheritance and so on. But how to store this inside my program?
I found two ways:
Parse xml while scanning (to internal representation)
Create classes for each element: parameter, parameter value, number of
parameters
Is there a real life example of implementing this thing? Or you may just say the best/common way to do this
Keeping in XML file will probably be the easiest method
If you like to keep config in your code - use code to do so. Here is good example of simple initialization:
Map<String, Integer> config = new HashMap<String, Integer>()
{{
put("One", 1);
put("Two", 2);
put("Three", 3);
}};
To this cases i love to use properties files
.properties is a file extension for files mainly used in Java related technologies to store the configurable parameters of an application. They can also be used for storing strings for Internationalization and localization; these are known as Property Resource Bundles.
Suppose you have a file in your package path.to.your with a properties file file.properties you can include them in you jar and recover the file with getClass().getResourceAsStream("/path/to/your/file.properties") then you can load the bundle, change the params, add new keys, etc, more info with MKYong - Java Properties file examples
I wonder if somebody has already met with a requirement to make a processing in Java depending on values defined in a .properties file and what would be the best approach to achieve that ? For example, a property file will have some key/value pairs like that:
file.input=csv
data.type=multi
data.separator=;
...etc
So in this case, depending on a property value(for example, 'csv'), I'll call CSV processing related classes, depending on 'data.type' value, I'll update the corresponding model values (e.g. class MultiCastXXX). The aim is to have something more or less generic like an API and be able to process no matter what is defined in a property file (of course with some conventions and restrictions applied). What do you think, any ideas ? Thank you.
I have a class like
class A {
private String property1;
private String property2;
private String property3;
// constructor , getters , setters
}
it is possible to get a list/array of the names of properties of this class in the order they appear in the source file ? like ["property1", "property2", "property3"]
The answer is that you can't. The information you require is not available at runtime from the .class files.
In some other parts of my code i need to "print" the data of this class in certain order. This class in the real case has a lot of properties and can change (as the order) so, i can write this array/list by myself to get the order i need but if it is possible to get it from the class it would be better for me.
Here are some better ways to solve this problem:
Sort the properties before printing, by name or by type name, or something that makes sense.
Embed an array in the bean class (or another class) that defines the bean property order.
Create a separate metadata file that specifies the bean property order.
You could do some build time pre-processing of your source code to extract the order of the properties and (say) write them to a file. But frankly, I think it is better to detach these aspects; e.g. so that your system integrators / end-users could tweak the property order without changing the source code.
This is not precisely possible. Class#getDeclaredFields makes no guarantee about the ordering of the fields returned. However, in the test I just conducted, the fields were indeed returned in their declaration order.
it is possible to get a list/array of the names of properties of this class
Yes, using Class.getDeclaredFields()
in the order they appear in the source file
No, not with any kind of guarantee unless you parse the source file.
How can I store an ArrayList and/or a HashMap variable using java.util.properties? If it's not possible what other class can I use to store application configuration?
If you just need to serialize your collections into Strings, I highly recommend XStream. It uses reflection to serialize a class into XML. There is documentation if the default behavior doesn't work for the class you want to serialize, but the following has worked for me every time so far:
XStream xstream = new XStream();
String xml = xstream.toXML(myObject);
MyClass deserializedObject = (MyClass)xstream.fromXML(xml);
assert deserializedObject.equals(myObject);
So... if "don't do that" doesn't work for you, then you need to encode the data somehow. One common technique is to prepend some string to the name of each element. For example if I have a map MyMap containing a->1, b->2, c->3, I might store in the properties file:
MyMap.a=1
MyMap.b=2
MyMap.c=3
For lists, you can do the same, just mapping indices to values. So if MyList contains {a,b,c}
MyList.0=a
MyList.1=b
MyList.2=c
This is a hack, and everything everyone else said is true. But sometimes you gotta do what you gotta do.
Properties is basically Map<String, String> meaning both key and value must be String objects. If you want more advanced configuration, you could go with Spring. Its an excellent framework and I use it in every project. Spring config files are extremely flexible.
java.util.Properties is only intended to be used with String keys and values. It does inherit the put() and putAll() methods from Hashtable, but it's rarely a good idea to use those to "cheat". Have you considered just storing your configuration information in a HashMap rather than a Properties object? You would have to customize the serialization a bit, but you're going to have to do that in any case as you can't take advantage of the default loading functionality of the Properties class.
Storing a HashMap would be easy, since each key and value in the Map can be represented by a corresponding key and value in the Properties object (see the setProperty method in Properties.
For the ArrayList you could do something similar, the keys would be the indexes and the values the items in the corresponding indexes.
In both cases, remember that a properties file only stores strings, so you'd have to devise a way to represent the keys and values in your objects as strings.