I've a swing application that has to connect to database for some resources, for this i used .properties file to store database properties and that can be read at runtime.
For this i am using the following code
public void readPropertiesFile(){
try{
InputStream is = ReadValues.class.getResourceAsStream(PROP_FILE);
Properties prop = new Properties();
prop.load(is);
String URL = prop.getProperty("DB_URL");
String user = prop.getProperty("DB_USER");
String pwd = prop.getProperty("DB_PWD");
is.close();
/* code to use values read from the file*/
}catch(Exception e){
System.out.println("Failed to read from " + PROP_FILE + " file.");
}
}
but i've to call this method whenever i want to connect to the database (for Connection object).
I know the thing that now processing is fast enough to run these lines in micro seconds, but it's for my own knowledge that suggest me the ways through which i can store these DB values when application starts or the first time user try to connect to DB for any operation in such objects or variables or constants that will be usable until the application restarts and can be called directly without reading the file.
P.S. : I know that the DB values will not change oftentimes, and if it happens than i'll be happy to restart my application :)
by making these static fields in a separate class, they will not be loaded until the first time you access URL,USER, or PASSWORD.
public class DbProps {
public static final String URL;
public static final String USER;
public static final String PASSWORD;
static {
try{
InputStream is = ReadValues.class.getResourceAsStream(PROP_FILE);
try {
Properties prop = new Properties();
prop.load(is);
URL = prop.getProperty("DB_URL");
USER = prop.getProperty("DB_USER");
PASSWORD = prop.getProperty("DB_PWD");
} finally {
is.close();
}
}catch(Exception e){
throw new RuntimeException("Failed to read from " + PROP_FILE + " file.", e);
}
}
}
You can nake a check condition which will check if it is first time then set the value other wise use the existing value
public static boolean isFirstTime = true;
public static String URL = true;
public static String user = true;
public static String pwd = true;
public void readPropertiesFile(){
if(isFirstTime){
try{
InputStream is = ReadValues.class.getResourceAsStream(PROP_FILE);
Properties prop = new Properties();
prop.load(is);
URL = prop.getProperty("DB_URL");
user = prop.getProperty("DB_USER");
pwd = prop.getProperty("DB_PWD");
isFirstTime = false;
is.close();
/* code to use values read from the file*/
}catch(Exception e){
System.out.println("Failed to read from " + PROP_FILE + " file.");
}
}
}
//use this URL user and pwd in your application
Here's a generic environment class for you. You can get your DB props like Environment.getEnvironment().getProperty("DB_URL"), etc.
public class Environment {
private static final String PROP_FILE = "somefilename";
private static final Environment singleton = new Environment();
public static Environment getEnvironment() {
return singleton;
}
private Properties properties = new Properties();
protected Environment() {
super();
loadProperties();
}
public Properties getProperties() {
return properties;
}
public String getProperty(String propertyName) {
return getProperty(propertyName, System.getProperty(propertyName));
}
public String getProperty(String propertyName, String defaultValue) {
return getProperties().getProperty(propertyName, defaultValue);
}
public void loadProperties() {
URL resourceURL = null;
try {
resourceURL = Thread.currentThread().getContextClassLoader()
.getResource(PROP_FILE);
getProperties().load(resourceURL.openStream());
System.out.println("Loaded properties from "
+ resourceURL.toExternalForm());
} catch (IOException ioe) {
System.err.println("Failed to load properties from "
+ resourceURL.toExternalForm());
}
}
}
Related
I'm creating a little java app and I'm trying to load the yml files based on config.yml lang set (en/it) but I can't find a way to load them, only the last one in an array is loaded which is "it" for me.
I know that my method is probably the worst solution for a language file, I'm open to every method that will help me with the problem. But I prefer an external lang_en/it file instead of internal ones (Or is it better internal?)
After I set the language, the app will self-update every text in every class.
static final Properties props = new Properties();
static WelcomeMessage main = new WelcomeMessage();
static File file = null;
static File folder = null;
static boolean os = main.os.startsWith("Windows");
public static void create() {
String[] lang = {"en", "it"};
for (String s : lang) {
file = new File(WelcomeMessage.user + "/AppData/Roaming/MyApp/lang_" + s + ".yml");
folder = new File(file.getParent());
SetLanguages(s);
}
if (!file.exists()) {
try {
if (os) {
folder.mkdir();
file.createNewFile();
} else {
file = new File(main.user + "/Library/Application Support/MyApp/config.yml");
folder.mkdir();
file.createNewFile();
}
} catch (Exception e) {
System.out.println(e + " " + file);
}
}
}
public static void SetLanguages(String lang) {
if (lang.equals("en")) {
store("Settings.Save", "Save");
store("Settings.ConfigPath", "Config Path");
store("Settings.Language", "Language");
store("Settings.Title", "Settings");
} else if (lang.equals("it")) {
store("Settings.Save", "Salva");
store("Settings.ConfigPath", "Percorso config");
store("Settings.Language", "Lingua");
store("Settings.Title", "Impostazioni");
}
}
public static String get(String value) {
String key = null;
try {
FileInputStream in = new FileInputStream(file);
props.load(in);
key = props.getProperty(value);
in.close();
} catch (Exception fnf) {
System.out.println(fnf);
}
return key;
}
public static void store(String value, String key) {
try {
FileOutputStream out = new FileOutputStream(file);
props.setProperty(value, key);
props.store(out, null);
out.close();
} catch (Exception fnf) {
System.out.println(fnf);
}
}
This is how I get a text from yml:
path.setText(Language.get("Settings.ConfigPath"));
language.setText(Language.get("Settings.Language"));
f.setTitle(Language.get("Settings.Title"));
save.setText(Language.get("Settings.Save"));
And this my Language.get(key)
public static String get(String value) {
String key = null;
try {
FileInputStream in = new FileInputStream(file);
props.load(in);
key = props.getProperty(value);
in.close();
} catch (Exception fnf) {
System.out.println(fnf);
}
return key;
}
I suggest the following changes:
Create a Settings class to hold the properties save, configPath, language and title. Even better if this class uses an immutable builder pattern, because once set, the properties will never change.
Create a SettingsFactory class with method getSettings(language). This class shall also have a field Map<String, Settings>. In the constructor (or a static block), first check if a file exists on the disk, and if yes, load it into the map. If not, populate the map, one entry for each language, and persist to the disk.
getSettings would simply return the value from the map corresponding to the given language.
The format of the file written to the disk is a different matter. You say YAML, but I'm not seeing any YAML specific code in your snippet. If you don't know how to write a map to YAML, open a different question.
I have an Email class which is abstract. It has several children: AuthenticationEmail, MarketingEmail, etc. I want to initialize value of a field (which is final static) with a string stored in an external file.
At first I though I could use Spring's #Value but it turned out that the class needs to be a component. Then I tried the following code (static initialization and etc.):
public abstract class UserAccountAuthenticationEmail extends Email implements Serializable {
#Value("${email.address.from.authentication}")
private final static String SENDER_EMAIL_ADDRESS;
static {
Properties prop = new Properties();
String propFileName = "config.properties";
InputStream inputStream;
if (inputStream != null) {
prop.load(inputStream);
inputStream = getClass().getClassLoader().getResourceAsStream(propFileName);
} else {
throw new FileNotFoundException("property file '" + propFileName + "' not found in the classpath");
}
}
#Override
public String getSender() {
return SENDER_EMAIL_ADDRESS;
}
}
It doesn't work either, as getClass is a non-static method and cannot be instantiated inside the static block.
How can I initialize the value of this variable from a file? and preferably only one time. Is there any standard method to do that? something like #Value, instead of manually reading from IO?
Hope it can help you. A static final variable can't be changed after the first initialization.
public class UserAccountAuthenticationEmail implements Serializable {
private final static String SENDER_EMAIL_ADDRESS =getVal();
public static String getVal() {
try {
Properties prop = new Properties();
String propFileName = "C:\\SMS\\config.properties";
InputStream inputStream;
inputStream = new FileInputStream(propFileName);
if (inputStream != null) {
prop.load(inputStream);
return prop.getProperty("email");
} else {
throw new FileNotFoundException("property file '" + propFileName + "' not found in the classpath");
}
}
catch (Exception e){
e.printStackTrace();
}
return "";
}
public static void main(String[] args) {
System.out.println(SENDER_EMAIL_ADDRESS);
}
}
Fixed it this way:
private final static String DEFAULT_SENDER_EMAIL_ADDRESS;
static {
String value = "";
try {
Properties prop = new Properties();
String propFileName = "application.properties";
InputStream inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream(propFileName);
if (inputStream != null) {
prop.load(inputStream);
value = prop.getProperty("email.authentication.sender");
}
}
catch (Exception e){
e.printStackTrace();
}
DEFAULT_SENDER_EMAIL_ADDRESS = value;
}
public String getSender() {
return DEFAULT_SENDER_EMAIL_ADDRESS;
}
I have int, float, boolean and string from Properties file. Everything has loaded in Properties. Currently, I am parsing values as I know expected value for particular key.
Boolean.parseBoolean("false");
Integer.parseInt("3")
What is better way of setting these constants values, If I don't know what could be primitive value datatype for a key.
public class Messages {
Properties appProperties = null;
FileInputStream file = null;
public void initialization() throws Exception {
appProperties = new Properties();
try {
loadPropertiesFile();
} catch (Exception e) {
throw new Exception(e.getMessage(), e);
}
}
public void loadPropertiesFile() throws IOException {
String path = "./cfg/message.properties";
file = new FileInputStream(path);
appProperties.load(file);
file.close();
}
}
Properties File.
messassge.properties
SSO_URL = https://example.com/connect/token
SSO_API_USERNAME = test
SSO_API_PASSWORD = Uo88YmMpKUp
SSO_API_SCOPE = intraday_api
SSO_IS_PROXY_ENABLED = false
SSO_MAX_RETRY_COUNT = 3
SSO_FLOAT_VALUE = 3.0
Constant.java
public class Constants {
public static String SSO_URL = null;
public static String SSO_API_USERNAME = null;
public static String SSO_API_PASSWORD = null;
public static String SSO_API_SCOPE = null;
public static boolean SSO_IS_PROXY_ENABLED = false;
public static int SSO_MAX_RETRY_COUNT = 0;
public static float SSO_FLOAT_VALUE = 0;
}
If you have a class of configuration values, like your Constants class, and you want to load all values from a configuration (properties) file, you can create a little helper class and use reflection:
public class ConfigLoader {
public static void load(Class<?> configClass, String file) {
try {
Properties props = new Properties();
try (FileInputStream propStream = new FileInputStream(file)) {
props.load(propStream);
}
for (Field field : configClass.getDeclaredFields())
if (Modifier.isStatic(field.getModifiers()))
field.set(null, getValue(props, field.getName(), field.getType()));
} catch (Exception e) {
throw new RuntimeException("Error loading configuration: " + e, e);
}
}
private static Object getValue(Properties props, String name, Class<?> type) {
String value = props.getProperty(name);
if (value == null)
throw new IllegalArgumentException("Missing configuration value: " + name);
if (type == String.class)
return value;
if (type == boolean.class)
return Boolean.parseBoolean(value);
if (type == int.class)
return Integer.parseInt(value);
if (type == float.class)
return Float.parseFloat(value);
throw new IllegalArgumentException("Unknown configuration value type: " + type.getName());
}
}
Then you call it like this:
ConfigLoader.load(Constants.class, "/path/to/constants.properties");
You can extend the code to handle more types. You can also change it to ignore missing properties, instead of failing like it does now, such that assignments in the field declaration will remain unchanged, i.e. be the default.
If you know the type of constant, you can use Apache Commons Collections.
For example, you can use some utilities method based on type of your constant.
booelan SSO_IS_PROXY_ENABLED = MapUtils.getBooleanValue(appProperties, "SSO_IS_PROXY_ENABLED", false);
String SSO_URL = MapUtils.getString(appProperties, "SSO_URL", "https://example.com/connect/token");
You can even use default values to avoid errors.
Dambros is right, every thing you store inside a Properties file is as a String value.
You can track your different primitive data types after retrieving properties value as below like ref. -
Java Properties File: How to Read config.properties Values in Java?
package crunchify.com.tutorial;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Properties;
/**
* #author Crunchify.com
*
*/
public class CrunchifyGetPropertyValues {
String result = "";
InputStream inputStream;
public String getPropValues() throws IOException {
try {
Properties prop = new Properties();
String propFileName = "config.properties";
inputStream = getClass().getClassLoader().getResourceAsStream(propFileName);
if (inputStream != null) {
prop.load(inputStream);
} else {
throw new FileNotFoundException("property file '" + propFileName + "' not found in the classpath");
}
Date time = new Date(System.currentTimeMillis());
// get the property value and print it out
String user = prop.getProperty("user");
String company1 = prop.getProperty("company1");
String company2 = prop.getProperty("company2");
String company3 = prop.getProperty("company3");
result = "Company List = " + company1 + ", " + company2 + ", " + company3;
System.out.println(result + "\nProgram Ran on " + time + " by user=" + user);
} catch (Exception e) {
System.out.println("Exception: " + e);
} finally {
inputStream.close();
}
return result;
}
}
and later convert to primitive -
How to convert String to primitive type value?
I suggest you to track your data types value by putting the key values inside String type switch statement and later retrieve the related data type value by using key name cases.
String type switch case is possible after Java 7.
Not entirely sure whether I exactly understand the problem but a possibility could be to include the type of the property value in the (String) value. So for example the properties you showed would become something like:
SSO_URL = URL:https://example.com/connect/token
SSO_API_USERNAME = STRING:test
SSO_API_PASSWORD = STRING:Uo88YmMpKUp
SSO_API_SCOPE = STRING:intraday_api
SSO_IS_PROXY_ENABLED = BOOLEAN:false
SSO_MAX_RETRY_COUNT = INTEGER:3
SSO_FLOAT_VALUE = FLOAT:3.0
During the parsing of the property values you first determine the type of the property by looking at the part before : and use the part after for the actual parsing.
private static Object getValue(Properties props, String name) {
String propertyValue = props.getProperty(name);
if (propertyValue == null) {
throw new IllegalArgumentException("Missing configuration value: " + name);
} else {
String[] parts = string.split(":");
switch(parts[0]) {
case "STRING":
return parts[1];
case "BOOLEAN":
return Boolean.parseBoolean(parts[1]);
....
default:
throw new IllegalArgumentException("Unknown configuration value type: " + parts[0]);
}
}
}
Follow the dropwizard configuration pattern where you define your constants using YAML instead of Properties and use Jackson to deserialize it into your Class. Other than type safety, dropwizard's configuration pattern goes one step further by allowing Hibernate Validator annotations to validate that the values fall into your expected ranges.
For dropwizard's example...
http://www.dropwizard.io/0.9.2/docs/getting-started.html#creating-a-configuration-class
For more information about the technology involved...
github.com/FasterXML/jackson-dataformat-yaml
hibernate.org/validator/
Spring Boot has ready to use and feature reach solution for type-safe configuration properties.
Definitely, use of the Spring just for this task is overkill but Spring has a lot of cool features and this one can attract you to right side ;)
You can define your configurable parameters as 'static' in your class of choice, and from a static init call a method that loads the parameter values from a properties file.
For example:
public class MyAppConfig {
final static String propertiesPath="/home/workspace/MyApp/src/config.properties";
static String strParam;
static boolean boolParam;
static int intParam;
static double dblParam;
static {
// Other static initialization tasks...
loadParams();
}
private static void loadParams(){
Properties prop = new Properties();
try (InputStream propStream=new FileInputStream(propertiesPath)){
// Load parameters from config file
prop.load(propStream);
// Second param is default value in case key-pair is missing
strParam=prop.getProperty("StrParam", "foo");
boolParam=Boolean.parseBoolean(prop.getProperty("boolParam", "false"));
intParam= Integer.parseInt(prop.getProperty("intParam", "1"));
dblParam=Double.parseDouble(prop.getProperty("dblParam", "0.05"));
} catch (IOException e) {
logger.severe(e.getMessage());
e.printStackTrace();
}
}
}
This might help:
props.getProperty("name", Integer.class);
This question already has answers here:
JAVA .properties file
(3 answers)
Closed 10 years ago.
hi all i am having an issue, i have a properties file, this stores all the save locations, i get the data from this file by :
public void loadProp() {
System.out.println("Loading properties");
InputStream in = this.getClass().getClassLoader().getResourceAsStream("config.properties"); //points to a properties file, this will load up destinations instead of having to declare them here
try {
configProp.load(in);
System.out.println(configProp.getProperty("destinationPDF"));
System.out.println(configProp.getProperty("destination"));
System.out.println(configProp.getProperty("fileList"));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("called get username");
username = FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();
System.out.println(username);
}
i then do this to assign the value to destination
public String destination = configProp.getProperty("destination");
but whenever i use destination i get a null value, however if i use configProp.getProperty("destination") i get the full path, what am i doing wrong here as i want the value to be point to destination as other classes depend on it
EDIT :
This class is called on by a command button (web app)
#ViewScoped
#ManagedBean(name = "fileUploadController")
public class FileUploadController {
public boolean isUploadComplete() { //to enable the next button once finished
return uploadComplete;
}
public void setUploadComplete(boolean uploadComplete) {
this.uploadComplete = uploadComplete;
}
public boolean isUploadComplete2() {
//to disable the file upload button, this will stop users uploading multiple files and over writing them as only the last file uploaded will be used
return uploadComplete;
}
public void setUploadComplete2(boolean uploadComplete) {
this.uploadComplete = uploadComplete;
}
/*
public void handleFileUpload(FileUploadEvent event) {
System.out.println("called");
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
*/
//
//Strings for fileUpload
//oadProp()
//public String fileList = "D:/Documents/NetBeansProjects/printing~subversion/fileupload/web/resources/Directory Files/directoryFiles.txt"; //
private Properties configProp = new Properties();
#PostConstruct
//System.out.println(destinationPDF);
//System.out.println(destination);
// Get the username from the login page, this is used to create a folder for each user
public void loadProp() {
System.out.println("Loading properties");
InputStream in = this.getClass().getClassLoader().getResourceAsStream("config.properties"); //points to a properties file, this will load up destinations instead of having to declare them here
try {
configProp.load(in);
System.out.println(configProp.getProperty("destinationPDF"));
System.out.println(configProp.getProperty("destination"));
System.out.println(configProp.getProperty("fileList"));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("called get username");
username = FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();
System.out.println(username);
}
//String destinationPDF = configProp.getProperty("destinationPDF"); Always makes a null no idea why yet
//private String destinationPDF = configProp.getProperty("destinationPDF");
public String destination = configProp.getProperty("destination");
private String username;
//public static String destination = "D:/Documents/NetBeansProjects/printing~subversion/fileupload/uploaded/"; // main location for uploads//TORNADO ONLY //"D:/My Documents/NetBeansProjects/printing~subversion/fileupload/uploaded/"; // USE ON PREDATOR ONLY
public static String NewDestination;
public static String UploadedfileName;
public static String CompletefileName;
//
//Strings for file copy
//
//private String destinationPDF = "D:/Documents/NetBeansProjects/printing~subversion/fileupload/web/resources/pdf/"; //USE ON TORNADO//"D:/My Documents/NetBeansProjects/printing~subversion/fileupload/web/resources/pdf/";//USE ON PREDATOR
private String NewdestinationPDF;
public static String PdfLocationViewable;
private boolean uploadComplete;
private boolean uploadComplete2;
//
public void File() {
above is the first bit of code for that class
the output in the console is :
INFO: buttonToUploadText invoked
INFO: Loading properties
INFO: D:/Documents/NetBeansProjects/printing~subversion/fileupload/web/resources/pdf/
INFO: D:/Documents/NetBeansProjects/printing~subversion/fileupload/Uploaded/
INFO: D:/Documents/NetBeansProjects/printing~subversion/fileupload/web/resources/Directory Files/directoryFiles.txt
INFO: called get username
INFO: null
INFO: destination is null
Your ordering is off. This is what will happen when your bean is instantiated by the container:
Constructor will be called
All injected fields will be resolved
PostConstruct will be called.
Currently, you are setting the destination value before your properties have been loaded up. A very simple solution to this problem is to simply set the destination value in your #PostConstruct handler.
#PostConstruct
public void loadProp() {
InputStream in = this.getClass().getClassLoader()
.getResourceAsStream("config.properties");
try {
configProp.load(in);
} catch (IOException e) {
e.printStackTrace();
}
destination = configProp.getProperty("destination");
}
One advantage of this method over others is that the destination property will be correctly set every time the loadProp method is called (as opposed to only once).
Replace this line
public String destination = configProp.getProperty("destination");
with
public String destination;
and provide a constructor:
public FileUploadController() {
loadProp();
this.destination = configProp.getProperty("destination");
}
Now, loadProp() will be called by the constructor, and you don't have to do it anymore.
I have a static util class that does some string manipulation on a bit sensitive data.
Prior to use of this class I need to initialize certain static variables with values, such as usernames/password, that I prefer to store in a .properties file.
I am not very familiar with how loading of .properties file work in Java, especially outside of *Spring DI *container.
Anyone can give me a hand/insight on how this can be done?
Thank you!
Addition: .properties file precise location is unknown, but it will be on the classpath. Sorta like classpath:/my/folder/name/myproperties.propeties
First, obtain an InputStream from which the properties are to be loaded. This can come from a number of locations, including some of the most likely:
A FileInputStream, created with a file name that is hard-coded or specified via a system property. The name could be relative (to the current working directory of the Java process) or absolute.
A resource file (a file on the classpath), obtained through a call to getResourceAsStream on the Class (relative to the class file) or ClassLoader (relative to the root of the class path). Note that these methods return null if the resource is missing, instead of raising an exception.
A URL, which, like a file name, could be hard-coded or specified via a system property.
Then create a new Properties object, and pass the InputStream to its load() method. Be sure to close the stream, regardless of any exceptions.
In a class initializer, checked exceptions like IOException must be handled. An unchecked exception can be thrown, which will prevent the class from being initialized. That, in turn, will usually prevent your application from running at all. In many applications, it might be desirable to use default properties instead, or fallback to another source of configuration, such as prompting a use in an interactive context.
Altogether, it might look something like this:
private static final String NAME = "my.properties";
private static final Properties config;
static {
Properties fallback = new Properties();
fallback.put("key", "default");
config = new Properties(fallback);
URL res = MyClass.getResource(NAME);
if (res == null) throw new UncheckedIOException(new FileNotFoundException(NAME));
URI uri;
try { uri = res.toURI(); }
catch (URISyntaxException ex) { throw new IllegalArgumentException(ex); }
try (InputStream is = Files.newInputStream(Paths.get(uri))) { config.load(is); }
catch (IOException ex) { throw new UncheckedIOException("Failed to load resource", ex); }
}
Check out java.util.Properties.
You can use a static initializer. So on the top of the class you can do:
static {
Properties props = new Properties();
InputStream steam = ...; // open the file
props.load(stream);
// process properties content
String username = props.getProperty("username");
}
Use either:
CurrentClassName.class.getResourceAsStream
new FileInputStream(File)
to get the input stream depending on if the class is in or out of the classpath. Then use
Properties.load
to load the properties.
It's been a while, but if I remember correctly you just do something like this:
Properties prop = new Properties();
prop.load(new FileInputStream(filename));
//For each property you need.
blah = prop.getProperty(propertyname);
Well with static Properties it would make sense to initialize them as a Singleton which will be loaded once in a class. Here's an example:
class Example
{
public final static String PROPSFILE = "test.properties";
private static Properties props;
protected static Properties getProperties()
{
if(props == null)
{
props = new Properties();
props.load(new FileInputStream(new File(PROPSFILE));
}
return props;
}
public static User getUser()
{
String username = getProperties().getProperty("username");
return new User(username);
}
}
If you use relative Pathnames you should make sure, that your classpath is setup righ.
for me MyClass.class.getClassLoader().getResourceAsStream(..) did the trick:
private static final Properties properties;
static {
Properties fallback = new Properties();
fallback.put(PROP_KEY, FALLBACK_VALUE);
properties = new Properties(fallback);
try {
try (InputStream stream = MyClass.class.getClassLoader().getResourceAsStream("myProperties.properties")) {
properties.load(stream);
}
} catch (IOException ex) {
// handle error
}
}
I agree with #Daff, maybe better to use singleton class...this what i have on my project for similar requirement, maybe it may help:
clients of the class can use it like this:
ConfigsLoader configsLoader = ConfigsLoader.getInstance("etc/configs.xml");
System.out.format("source dir %s %n", configsLoader.getSourceDir());
and then the class:
public class ConfigsLoader {
private String sourceDir;
private String destination;
private String activeMqUrl;
private static Logger log = Logger.getLogger(ConfigsLoader.class.getName());
private static ConfigsLoader instance = null;
private ConfigsLoader(String configFileName) {
log.info("loading configs");
Properties configs = new Properties();
try {
configs.loadFromXML(new FileInputStream(configFileName));
sourceDir = configs.getProperty("source.dir");
destination = configs.getProperty("destination");
activeMqUrl = configs.getProperty("activemqconnectionurl");
configs.setProperty("lastLoaded", new SimpleDateFormat("yyyy-M-d HH:mm").format(new Date()));
configs.storeToXML(new FileOutputStream(configFileName), "saving last modified dates");
} catch (InvalidPropertiesFormatException e) {
log.log(Level.SEVERE,"Error occured loading the properties file" ,e);
} catch (FileNotFoundException e) {
log.log(Level.SEVERE,"Error occured loading the properties file" ,e);
} catch (IOException e) {
log.log(Level.SEVERE,"Error occured loading the properties file" ,e);
}
}
public static ConfigsLoader getInstance(String configFileName) {
if(instance ==null) {
instance = new ConfigsLoader(configFileName);
}
return instance;
}
public String getSourceDir() {
return sourceDir;
}
public void setSourceDir(String sourceDir) {
this.sourceDir = sourceDir;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
public String getActiveMqUrl() {
return activeMqUrl;
}
public void setActiveMqUrl(String activeMqUrl) {
this.activeMqUrl = activeMqUrl;
}
}
I did this finally using getResourceAsStream() fuction associated with the class in which the static code block is being written.
//associate Property and ImputStream imports
public class A {
static Properties p;
static {
p = new Properties();
try {
InputStream in = A.class.getResourceAsStream("filename.properties");
p.load(in);
} catch (FileNotFoundException e) {
System.out.println("FileNotFoundException");
e.printStackTrace();
} catch (IOException e) {
System.out.println("IOException");
e.printStackTrace();
}
}
.
.
.
}