stackoverflow, please help me. I have a small web application (Servlet + jsp). Unit test passed correctly, but after deploy my Factory isn't able to create instances of my DAOs, because after action "Property property = new Property();" property = null. Why?(
public class DAOFactory <T>{
private String daoType;
private String propertyFilePath;
private Properties property;
private FileInputStream fis;
private static Logger LOGGER;
private String propertyKey;
public DAOFactory(String propertyFilePath,String propertyKey) {
this(propertyKey);
this.propertyFilePath = propertyFilePath;
}
public DAOFactory(String propertyKey) {
propertyFilePath = "src/main/resources/dao_factory.properties";
LOGGER = LoggerFactory.getLogger(DAOFactory.class);
this.propertyKey = propertyKey;
try {
property = new Properties();
fis = new FileInputStream(propertyFilePath);
property.load(fis);
} catch (FileNotFoundException ex) {
LOGGER.error("Property file " + propertyFilePath + " doesn't exist", ex);
} catch (IOException ex) {
LOGGER.error("Unable to download Property file: " + propertyFilePath, ex);
}
System.err.println("fis: " + fis);
System.err.println("propertyKey: " + propertyKey);
System.err.println("property: " + property);
daoType = property.getProperty(propertyKey);
System.err.println("daoType: " + daoType);
}
public T getInstance () throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
Class c = Class.forName(daoType);
Method method = c.getDeclaredMethod("getInstance");
return (T) method.invoke(null, null);
}
}
When I try to use my DAOFactory,
DAOFactory<BookDAO> daoFactory= new DAOFactory(""BookDAO"); // or even new DAOFactory("src/main/resources/dao_factory.properties","BookDAO");
I've got
IN TESTS
fis: java.io.FileInputStream#5025a98f
propertyKey: BookDAO
property: {BookDAO=com.softserve.siniaieva.bibliophile.dao.impl.BookDAOImitation, ReaderDAO=com.softserve.siniaieva.bibliophile.dao.impl.ReaderDAOImitation}
daoType: com.softserve.siniaieva.bibliophile.dao.impl.BookDAOImitation
WHEN TOMCAT CREATES DAOFactory
fis: null
propertyKey: BookDAO
property: null
daoType: null
Should I add smth in web.xml for Tomcat to make it see FileInputStream ?
The issue is likely to do with this
propertyFilePath = "src/main/resources/dao_factory.properties";
The src directory won't be available after packaging, and things instead will be respectively moved to the bin directory. Give something like the following a go
DAOFactory.class.getResourceAsStream("dao_factory.properties")
You can read more about this here.
Related
I am using mockito-junit to test a piece of my code. As progressing I found out that there was an interface implemented in the main file which I was testing, when the test was running I found that the line where interface method is called get's covered but the real method doesn't get's covered.
This the code for the main file:
public class ExtractCurrencyDataTask {
private static final Logger LOGGER = LoggerFactory.getLogger(ExtractCurrencyDataTask.class);
#Autowired
private ExtractCurrencyService extractCurrencyService;
public void writeCurrencyListToFile(List<Currency> currencyList) {
if (currencyList != null && !currencyList.isEmpty()) {
String dir = "A path";
String fileName = "A filename";
String writeToFile = dir + "/" + fileName + ".writing";
String renameFile = dir + "/" + fileName + ".dat";
BufferedWriter writer = null;
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter(writeToFile);
writer = new BufferedWriter(fileWriter);
extractCurrencyService.extractCurrencyList(currencyList, writer);
} catch (Exception e) {
throw new RuntimeException("Error writing Currency codes", e);
} finally {
if (writer != null) {
try {
writer.close();
fileWriter.close();
} catch (IOException e) {
LOGGER.info("Exception occured while closing the file writer", e);
}
moveFile(writeToFile, renameFile);
}
}
}
}
private void moveFile(String writeToFile, String renameFile) {
try {
FileUtils.moveFile(FileUtils.getFile(writeToFile), FileUtils.getFile(renameFile));
} catch (IOException e) {
LOGGER.info("Exception occured while moving file from writing to dat", e);
}
}
Here extractCurrencyService is the interface which I have mentioned.
The interface:
public interface ExtractCurrencyService {
public void extractCurrencyList(List<Currency> currency, Writer writer);
}
This the method definition which is done another file which implements same interface Filename:ExtractCurrencyServiceImpl.java
public class ExtractCurrencyServiceImpl implements ExtractCurrencyService {
private static final String SEP = "|";
private static final String NEWLINE = "\n";
#Override
public void extractCurrencyList(List<Currency> currencyList, Writer writer) {
if (currencyList != null) {
currencyList.forEach(currency -> {
String code = currency.getCode();
String name = currency.getName() == null ? "" : currency.getName();
Long noOfDecimals = currency.getNumberOfDecimals();
RoundingMethodValue roundingMethod = currency.getRoundingMethod();
boolean isDealCurrency = currency.isDealCurrency();
String description = currency.getDescription() == null ? "" : currency.getDescription();
try {
writer.write(createCurrencyDataLine(code,
name,
noOfDecimals,
roundingMethod,
isDealCurrency,
description));
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
}
private String createCurrencyDataLine(String code,
String name,
Long noOfDecimals,
RoundingMethodValue roundingMethod,
boolean isdealCurrency,
String description) {
return code + SEP + name + SEP + noOfDecimals.toString() + SEP + roundingMethod.toString() + SEP
+ isdealCurrency + SEP + description + NEWLINE;
}
public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
Map<Object, Boolean> map = new ConcurrentHashMap<>();
return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
}
This is the test file:
#RunWith(MockitoJUnitRunner.class)
public class ExtractCurrencyDataTaskTest {
#Mock
private Currency mockCurrency;
#Mock
private ExtractCurrencyService mockExtractCurrencyService;
#Mock
private BufferedWriter mockBufferWriter;
#Mock
private Bean mockBean;
#InjectMocks
private ExtractCurrencyDataTask extractCurrencyDataTask;
#Test
public void writeCurrencyListToFileTest() {
List<Currency> currencyList = new ArrayList();
when(mockCurrency.getCode()).thenReturn("USD");
when(mockCurrency.getNumberOfDecimals()).thenReturn((long) 2);
when(mockCurrency.getRoundingMethod()).thenReturn(enum value);
when(mockCurrency.isDealCurrency()).thenReturn(true);
when(mockCurrency.getName()).thenReturn("US Dollars");
when(mockCurrency.getDescription()).thenReturn("Currency Description");
currencyList.add(mockCurrency);
extractCurrencyDataTask.writeCurrencyListToFile(currencyList);
}
}
This the configuration for Autowired bean
#Bean
public ExtractCurrencyService extractCurrencyService() {
return new ExtractCurrencyServiceImpl();
}
As you can see the real output of this process is a file will be created in a path mentioned with some data. Here in this test I am mocking the data and passing it to main file. Main file is the created file in respective path but there is no data in the file.
The data writing part is done by the interface method. This is the part where I need help.
Thanks in advance....
You are injecting a mock of ExtractCurrencyService into your tested class. So the test is running with this mock instance instead of ExtractCurrencyServiceImpl. The current behaviour is that your ExtractCurrencyDataTasktested class is calling to extractCurrencyService#extractCurrencyList, but this extractCurrencyService is a mock, not your real implementation, so the call is done but it does nothing.
If you want to unit test ExtractCurrencyDataTask then thats ok, but maybe you should assert the call to extractCurrencyService#extractCurrencyList is done in the way you expect.
If you want to unit test ExtractCurrencyServiceImpl then create a unit test for this class.
If you want to test the interaction between these two classes then create an integration test where ExtractCurrencyDataTask has injected a real instance of ExtractCurrencyServiceImpl, not a mock.
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);
So i am trying to learn Hibernate/JPA and i was wondering if there is something similar to .NET's Entity Framework migrations that i can use.
I like Code First (Class -> Schema) approach, but the auto generated sql queries may do strange (and dangerous) things to a database. I want to verify the generated sql query and then decide if i want to update the database schema.
I have enabled the show_sql property. I run the project in debug mode in order to check the generated query and then stop / continue the execution.
Is there a more elegant (proper?) way to do what i want?
Edit: also is there an icremental schema update feature? For instance if i rename a field of my Model's Class, then Hibernate/JPA does the following thing:
If hbm2ddl.auto=create-drop then it will drop the table and
recreate it (data loss).
If hbm2ddl.auto=update then it will add a
new colunmn with the new name.
What i want is to alter the existing table.
Yes, there is a schema generator class.
org.hibernate.tool.hbm2ddl.SchemaExport
Here's a sample code on how I use it (note that this was very highly inspired from a post here)
package com.mypackage.jpa.util;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
public class SchemaGenerator {
private Configuration cfg;
public static void main(String[] args) throws Exception {
File f = new File(".");
String directory = f.getAbsoluteFile() + "/src/main/resources/ddl/generated/";
String packageName[] = { "com.mypackage.jpa", "com.mypackage.jpa.legacy", "com.mypackage.jpa.local",
"com.mypackage.jpa.local.impl" };
SchemaGenerator gen = new SchemaGenerator(packageName);
gen.generate(Dialect.MYSQL, directory);
}
#SuppressWarnings("rawtypes")
public SchemaGenerator(String[] packagesName) throws Exception {
cfg = new Configuration();
cfg.setProperty("hibernate.hbm2ddl.auto", "create");
for (String packageName : packagesName) {
for (Class clazz : getClasses(packageName)) {
cfg.addAnnotatedClass(clazz);
}
}
}
#SuppressWarnings("rawtypes")
private List<Class> getClasses(String packageName) throws Exception {
File directory = null;
try {
ClassLoader cld = getClassLoader();
URL resource = getResource(packageName, cld);
directory = new File(resource.getFile());
} catch (NullPointerException ex) {
throw new ClassNotFoundException(packageName + " (" + directory + ") does not appear to be a valid package");
}
return collectClasses(packageName, directory);
}
private ClassLoader getClassLoader() throws ClassNotFoundException {
ClassLoader cld = Thread.currentThread().getContextClassLoader();
if (cld == null) {
throw new ClassNotFoundException("Can't get class loader.");
}
return cld;
}
private URL getResource(String packageName, ClassLoader cld) throws ClassNotFoundException {
String path = packageName.replace('.', '/');
URL resource = cld.getResource(path);
if (resource == null) {
throw new ClassNotFoundException("No resource for " + path);
}
return resource;
}
#SuppressWarnings("rawtypes")
private List<Class> collectClasses(String packageName, File directory) throws ClassNotFoundException {
List<Class> classes = new ArrayList<>();
if (directory.exists()) {
String[] files = directory.list();
for (String file : files) {
if (file.endsWith(".class")) {
// removes the .class extension
classes.add(Class.forName(packageName + '.' + file.substring(0, file.length() - 6)));
}
}
} else {
throw new ClassNotFoundException(packageName + " is not a valid package");
}
return classes;
}
private void generate(Dialect dialect, String directory) {
cfg.setProperty("hibernate.dialect", dialect.getDialectClass());
SchemaExport export = new SchemaExport(cfg);
export.setDelimiter(";");
export.setOutputFile(directory + "ddl_" + dialect.name().toLowerCase() + ".sql");
export.setFormat(true);
export.execute(true, false, false, false);
}
private static enum Dialect {
ORACLE("org.hibernate.dialect.Oracle10gDialect"), MYSQL("org.hibernate.dialect.MySQLDialect"), HSQL(
"org.hibernate.dialect.HSQLDialect"), H2("org.hibernate.dialect.H2Dialect");
private String dialectClass;
private Dialect(String dialectClass) {
this.dialectClass = dialectClass;
}
public String getDialectClass() {
return dialectClass;
}
}
}
Hi I have a class ReadProperty which has a method ReadPropertyFile of return type Myclass which read the parameter values from a property file and return Myclass object. I need help to test the ReadPropertyFile method with JUnit, if possible with mock files and mock object.
Here is my code.
import java.io.FileInputStream;
import java.util.Properties;
public class ReadProperty {
public Myclass ReadPropertyFile(String fileName) {
Myclass myclass = null;
String testparam = null;
FileInputStream fis = null;
Properties prop = new Properties();
try {
fis = new FileInputStream(fileName);
try {
prop.load(fis);
System.out.println("Load Property file : Success !");
} catch (Exception ex) {
System.out.println("Load Property file : Exception : " + ex.toString());
}
/*
* loading the properties
*/
try {
testparam = prop.getProperty("testparam");
System.out.println("testparam Type : " + testparam);
} catch (Exception ex) {
System.out.println("testparam Type : " + ex.toString());
}
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("Property file read fail : " + ex.toString());
System.exit(1);
}
Myclass = new Myclass(testparam);
return Myclass;
} }
I don't think that you really need to mock anything here. You want to test if your property reader is able to access and read a file as you expect, so test exactly that. For regular properties it can go like this:
#Test
public void shouldReadPropFileFromSingleString() {
final Properties p = PropertiesLoader
.loadProperties("propfile");
assertNotNull(p);
assertFalse(p.isEmpty());
for (final Entry<Object, Object> e : p.entrySet()) {
assertEquals(expectedProperties.get(e.getKey()), e.getValue());
}
}
For your case, you can adapt it:
#Test
public void shouldReadCorrectProp() {
final MyClass p = ReadProperty
.readPropertyFile("propfile");
assertNotNull(p);
assertEquals(expectedProperty, p);
}
You may also want to test the sad path - what happens if the property file is not found, are any fallback properties available etc.
BTW, I would advise changing the method name, since reading a property file is not the primary concern of your method - retrieving a property is. Better yet, decompose the method into a getProperty and a readPropertyFile method, where the first method calls the second. So you will have a cleaner design according to Separaton of Concerns
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();
}
}
.
.
.
}