We have a connection pooling component (JAR file) for one of our application. As of now the application connection details are bundled with-in the JAR file (in .properties file).
Can we make it more generic? Can we have the client tell the properties file details (both the path and the file name) and use the JAR to get the connection?
Does it make sense to have something like this in the client code:
XyzConnection con = connectionIF.getConnection(uname, pwd);
Along with this, the client will specify (somehow???) the properties file details that has the URLs to connect, timeout etc.
Simplest way, use the -D switch to define a system property on a java command line.
That system property may contain a path to your properties file.
E.g
java -cp ... -Dmy.app.properties=/path/to/my.app.properties my.package.App
Then, in your code you can do ( exception handling is not shown for brevity ):
String propPath = System.getProperty( "my.app.properties" );
final Properties myProps;
if ( propPath != null )
{
final FileInputStream in = new FileInputStream( propPath );
try
{
myProps = Properties.load( in );
}
finally
{
in.close( );
}
}
else
{
// Do defaults initialization here or throw an exception telling
// that environment is not set
...
}
http://www.javaworld.com/javaworld/javaqa/2003-08/01-qa-0808-property.html
multiple approaches are available, the article above provides more details
ClassLoader.getResourceAsStream ("some/pkg/resource.properties");
Class.getResourceAsStream ("/some/pkg/resource.properties");
ResourceBundle.getBundle ("some.pkg.resource");
Just load the properties from file, something like
Properties properties = new Properties();
InputStreamReader in = null;
try {
in = new InputStreamReader(new FileInputStream("propertiesfilepathandname"), "UTF-8");
properties.load(in);
} finally {
if (null != in) {
try {
in.close();
} catch (IOException ex) {}
}
}
Note how the encoding is explicitly specified as UTF-8 above. It could also be left out if you accept the default ISO8859-1 encoding, but beware with any special characters then.
This is my solution. First looking for app.properties in startup folder, if does not exists try to load from your JAR package:
File external = new File("app.properties");
if (external.exists())
properties.load(new FileInputStream(external));
else
properties.load(Main.class.getClassLoader().getResourceAsStream("app.properties"));
Simplest way is below. It will load application.properties from cfg folder outside of the jar file.
Directory Structure
|-cfg<Folder>-->application.properties
|-somerunnable.jar
Code:
Properties mainProperties = new Properties();
mainProperties.load(new FileInputStream("./cfg/application.properties"));
System.out.println(mainProperties.getProperty("error.message"));
In netbeans I needed to load application.properties from conf/ folder outside of the jar file.
Therefore I wrote :
public static String getProperty(String FileName, String Prop)
{
try {
FIS = new FileInputStream( "./../conf/"+FileName);
Properties properties;
(properties = new Properties()).load(FIS);
for(Enumeration propKeys = properties.propertyNames();
propKeys.hasMoreElements();){
String tmpKey = (String) propKeys.nextElement();
String tmpValue = properties.getProperty(tmpKey);
tmpValue = tmpValue.trim();
if (tmpKey.equals(Prop)){
//System.out.println(tmpKey +"="+tmpValue);
properties.put(tmpKey, tmpValue);
Value = properties.getProperty(Prop);
break;
}
}
if (Value==null){
throw new Exception("La Propiedad : "+Prop+" no Se encuentra en el Archivo de Configuracion");
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return Value;
}
For Eclipse apply the following:
FIS = new FileInputStream( "../conf/"+FileName);
public static String getPropertiesValue(String propValue) {
Properties props = new Properties();
fileType = PCLLoaderLQIOrder.class.getClassLoader().getResourceAsStream(propFileName);
if (fileType != null) {
try {
props.load(fileType);
} catch (IOException e) {
logger.error(e);
}
} else {
try {
throw new FileNotFoundException("Property file" + propFileName + " not found in the class path");
} catch (FileNotFoundException e) {
logger.error(e);
}
}
String propertiesValue = props.getProperty(propValue);
return propertiesValue;
}
above methods works for me, just store your property file into directory from where to run your jar and provide that name in place of propFileName, when you want any value from property just call getPropertyValue("name").
Related
I've been trying to read a properties file and want it to be dynamic, I'm doing this in aws-cdk.
My project layout:
Main Project
resources
config.properties
src
main/java/com/myorg
xxxstage.java
The class xxxstage.java has following code:
public class xxxstage extends Stage {
public xxxstage(final Construct scope, final String id) {
this(scope, id, null);
}
public xxxstage(final Construct scope, final String id, final StageProps props) {
super(scope, id, props);
String account = null;
InputStream inputStream = null;
try {
Properties prop = new Properties();
String propFileName = "resources/config.properties";
inputStream = this.getClass().getClassLoader().getResourceAsStream(propFileName);
System.out.println("inputStream is -> "+inputStream);
if (inputStream != null) {
prop.load(inputStream);
} else {
throw new FileNotFoundException("property file '" + propFileName + "' not found in the classpath");
}
// get the property value and print it out
account = prop.getProperty("account.id");
System.out.println("account id -> "+account);
} catch (Exception e) {
System.out.println("Exception: " + e);
} finally {
try{
inputStream.close();
}
catch (Exception e){
System.out.println("Exception: " + e);
}
}
new xxxStack(this, "xxxStack", StackProps.builder()
.env(new Environment.Builder()
.account(account)
.region("us-east-1")
.build())
.build());
}
}
The line where I'm trying to print System.out.println("inputStream is -> "+inputStream); is showing null, and hence the FileNotFoundException.
It worth noting that this is working fine when I run it on local java-project, its however failing during build phase of the aws-codepipeline.
In the pipeline build phase I'm getting:
inputStream is -> null
Exception: java.io.FileNotFoundException: property file 'resources/config.properties' not found in the classpath
Exception: java.lang.NullPointerException
Can someone please help?
EDIT 1 - Adding environment variables:
Environment Vars
PATH=/root/.npm/_npx/230/bin:/usr/local/bin/sbt/bin:/root/.phpenv/shims:/root/.phpenv/bin:/root/.goenv/shims:/root/.goenv/bin:/go/bin:/root/.phpenv/shims:/root/.phpenv/bin:/root/.pyenv/shims:/root/.pyenv/bin:/root/.rbenv/shims:/usr/local/rbenv/bin:/usr/local/rbenv/shims:/root/.dotnet/:/root/.dotnet/tools/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/tools:/codebuild/user/bin
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI=/v2/credentials/xxx-xxx-xxx
CODEBUILD_CI=true
CODEBUILD_AUTH_TOKEN=xxx-xxx-xxx
JAVA_8_HOME=/usr/lib/jvm/java-1.8.0-amazon-corretto
JDK_8_HOME=/usr/lib/jvm/java-1.8.0-amazon-corretto
CODEBUILD_BUILD_ARN=arn:aws:codebuild:us-east-1:821518525729:build/pipelinePipelinexxx-C-xxx-xxx-xxx
CODEBUILD_GOPATH=/codebuild/output/src123245
GOLANG_15_VERSION=1.15.12
CODEBUILD_BUILD_SUCCEEDING=1
GOENV_DISABLE_GOPATH=1
JRE_HOME=/usr/lib/jvm/java-11-amazon-corretto
CDK_DEFAULT_REGION=us-east-1
JAVA_11_HOME=/usr/lib/jvm/java-11-amazon-corretto
PHP_74_VERSION=7.4.13
CODEBUILD_SOURCE_VERSION=arn:aws:s3:::pipelinexxxstack-pipelinexxxartifacts-1cacuj92rramf/ServiceDeploymentPip/(user)/c1BGqPX
RUBY_BUILD_SRC_DIR=/usr/local/rbenv/plugins/ruby-build
JDK_HOME=/usr/lib/jvm/java-11-amazon-corretto
PWD=/codebuild/output/src12345/src
CODEBUILD_CONTAINER_NAME=default
PYTHON_37_VERSION=3.7.10
CODEBUILD_START_TIME=1642556874326
CDK_DEFAULT_ACCOUNT=12345
AWS_REGION=us-east-1
PYTHON_38_VERSION=3.8.10
CODEBUILD_BUILD_URL=https://us-east-1.console.aws.amazon.com/codebuild/home?region=us-east-1#/builds/pipelinePipelinexxxSynthC-ofdfmXGrWl5m:xxx-xxx-xxx/view/new
CDK_OUTDIR=cdk.out
DOTNET_31_SDK_VERSION=3.1.404
CODEBUILD_BUILD_ID=pipelinePipelinexxxSynthC-ofdfmXGrWl5m:xxx-xxx-xxx
GOPATH=/go:/codebuild/output/src12345
CODEBUILD_RESOLVED_SOURCE_VERSION=xxx-xxx-xxx
OLDPWD=/codebuild/output/src12345/src
RUBY_26_VERSION=2.6.6
AWS_STS_REGIONAL_ENDPOINTS=regional
DOTNET_ROOT=/root/.dotnet
_PROJECT_CONFIG_HASH=xxx-xxx-xxx
CODEBUILD_AGENT_ENDPOINT=http://127.0.0.1:port
LC_CTYPE=C.UTF-8
JRE_8_HOME=/usr/lib/jvm/java-1.8.0-amazon-corretto/jre
CODEBUILD_BUILD_IMAGE=aws/codebuild/standard:5.0
PYYAML_VERSION=5.4.1
FORCE_COLOR=0
CODEBUILD_BMR_URL=https://CODEBUILD_AGENT:port
JAVA_HOME=/usr/lib/jvm/java-11-amazon-corretto
CODEBUILD_SRC_DIR=/codebuild/output/src12345/src
AWS_DEFAULT_REGION=us-east-1
AWS_EXECUTION_ENV=AWS_ECS_EC2
ECS_CONTAINER_METADATA_URI=http://169.254.170.2/v3/xxx-xxx-xxx
ECS_CONTAINER_METADATA_URI_V4=http://169.254.170.2/v4/xxx-xxx-xxx
CODEBUILD_INITIATOR=codepipeline/ServicexxxPipeline
MAVEN_OPTS= -Dmaven.wagon.httpconnectionManager.maxPerRoute=2
CDK_CONTEXT_JSON={"#aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId":true,"#aws-cdk/core:enableStackNameDuplicates":true,"aws-cdk:enableDiffNoFail":true,"#aws-cdk/core:stackRelativeExports":true,"#aws-cdk/aws-ecr-assets:dockerIgnoreSupport":true,"#aws-cdk/aws-secretsmanager:parseOwnedSecretName":true,"#aws-cdk/aws-kms:defaultKeyPolicies":true,"#aws-cdk/aws-s3:grantWriteWithoutAcl":true,"#aws-cdk/aws-ecs-patterns:removeDefaultDesiredCount":true,"#aws-cdk/aws-rds:lowercaseDbIdentifier":true,"#aws-cdk/aws-efs:defaultEncryptionAtRest":true,"#aws-cdk/aws-lambda:recognizeVersionProps":true,"#aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021":true,"#aws-cdk/core:newStyleStackSynthesis":true,"aws:cdk:enable-path-metadata":true,"aws:cdk:enable-asset-metadata":true,"aws:cdk:version-reporting":true,"aws:cdk:bundling-stacks":[]}
CODEBUILD_LOG_PATH=xxx-xxx-xxx
CODEBUILD_EXECUTION_ROLE_BUILD=
CODEBUILD_BUILD_NUMBER=31
GOLANG_16_VERSION=1.16.4
PHP_73_VERSION=7.3.25
CODEBUILD_FE_REPORT_ENDPOINT=https://codebuild.us-east-1.amazonaws.com/
CODEBUILD_LAST_EXIT=0
AWS_NODEJS_CONNECTION_REUSE_ENABLED=1
MAVEN_CMD_LINE_ARGS= -e -q compile exec:java
NUGET_XMLDOC_MODE=skip
DOTNET_5_SDK_VERSION=5.0.202
NODE_12_VERSION=12.22.2
PYTHON_39_VERSION=3.9.5
CDK_CLI_VERSION=2.8.0
NODE_14_VERSION=14.17.2
MAVEN_PROJECTBASEDIR=/codebuild/output/src12345/src
CDK_CLI_ASM_VERSION=16.0.0
JRE_11_HOME=/usr/lib/jvm/java-11-amazon-corretto
RUBY_27_VERSION=2.7.2
HOSTNAME=12345
JDK_11_HOME=/usr/lib/jvm/java-11-amazon-corretto
CODEBUILD_PROJECT_UUID=xxx-xxx-xxx
PHP_80_VERSION=8.0.0
CODEBUILD_KMS_KEY_ID=arn:aws:kms:us-east-1:(account-num):alias/aws/s3
HOME=/root
I found an answer here and it worked for me. The location of properties file matters.
Am trying to ready properties file which is presented in my project directory src/test/resources/properties/api/. But this way is not working and its give me file not found exception.
Please find my code below :
public Properties extractProperties() throws IOException {
InputStream configReader= null;
String env = getProperty("tuf.environment");
try {
configReader = new FileInputStream(new File("src/test/resources/properties/api/"+env+".properties")); // throwing exception
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
prop.load(configReader);
return prop;
}
I would do it the following way. Please note that the extractProperties() method will return an empty Properties object if the file was not found. Please also note the try-with-resources statement which will auto-close the InputStream.
public Properties extractProperties() throws IOException {
String env = getProperty("tuf.environment");
Properties prop = new Properties();
try (InputStream in = this.getClass().getResourceAsStream("/properties/api/" + env + ".properties")) {
prop.load(in);
} catch (Exception e) {
e.printStackTrace();
}
return prop;
}
Judging from your path you are using either Maven or Gradle as it looks like the default structure used by them. Which means src/test/resources points to the root of the classpath, so there is no src/test/resources. (The same applies to src/main/resources as well!).
So if you want to load it yuo would need to remove the src/test/resources part of the loading.
Next if this is run from a packaged application loading a File won't work as it isn't a File. The File needs to be a physical file on the filesystem and not inside an archive.
Taking all that into account you should be able to load the properties using the following
public Properties extractProperties() throws IOException {
String env = getProperty("tuf.environment");
String resource = "/properties/api/"+env+".properties";
try (InputStream in = getClass().getResourceAsStream(resource)) {
prop.load(in);
return prop;
}
}
Try something like below
public Properties extractProperties() throws IOException {
Properties prop=new Properties();
String env = getProperty("tuf.environment");
String mappingFileName = "/properties/api/" + env+ ".properties";
Resource resource = resourceLoader.getResource("classpath:" + mappingFileName);
try (InputStream inputStream = resource.getInputStream();
BufferedReader bufferedInputStream = new BufferedReader(new InputStreamReader(inputStream))) {
prop.load(bufferedInputStream);
} catch IOException ie) {
//handle exception
}
return prop;
}
Probably env is not what you think it is. Why not list all files in that directory?
You can print with https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/nio/file/Files.html#list(java.nio.file.Path)
With the relevant directory:
Path apiDir = Paths.get("src/test/resources/properties/api/");
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.
having a lil issue, i have create a properties file :
config.properties located in ../resource/config.properties
this is the file currently :
destinationPDF=D:/Documents/NetBeansProjects/printing~subversion/fileupload/web/resources/pdf/
destination="D:/Documents/NetBeansProjects/printing~subversion/fileupload/Uploaded/
fileList =D:/Documents/NetBeansProjects/printing~subversion/fileupload/web/resources/Directory Files/directoryFiles.txt
have i done the properties file ok ?
also i want to access this file and load the variables into a class
i have tried
public void loadProp() {
try {
prop.load(new FileInputStream("../resources/config.properties"));
System.out.println(prop.getProperty("destinationPDF"));
System.out.println(prop.getProperty("destination"));
System.out.println(prop.getProperty("fileList"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
but now the class will not compile becuase it can not find variable destination for example, so how do i load the variables from the file, and do i still need to declear the variable in the class ?
sorry if these are silly questions, first time using properties !
i do not get this error if i put in the variables normally like
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
EDIT:
have now
private Properties configProp = new Properties();
public void loadProps() {
InputStream in = this.getClass().getClassLoader().getResourceAsStream("../resources/config.properties");
try {
configProp.load(in);
} catch (IOException e) {
e.printStackTrace();
}
}
EDIT 2:
public void loadProp() {
InputStream in = this.getClass().getClassLoader().getResourceAsStream("../resources/config.properties");
try {
prop.load(in);
System.out.println(prop.getProperty("destinationPDF"));
System.out.println(prop.getProperty("destination"));
System.out.println(prop.getProperty("fileList"));
} catch (IOException e) {
e.printStackTrace();
}
}
Properties prop = new Properties();
private String destinationPDF = prop.getProperty("destinationPDF");
public String destination = prop.getProperty("destination");
it is working, no erors etc but destination and destinationPDF are passing null values
You seem to misunderstand what properties files are. They're just data. They don't contain Java code, and aren't used to declare variables. To get the value associated to the key destinationPDF in the properties file, you need to call
String destinationPDF = prop.getProperty("destinationPDF");
after having initialized the prop variable and loaded the file using prop.load(new FileInputStream(...)). And then you'll have a variable initialized with the value of the key.
Side note: please respect the Java naming conventions: variables start with a lower-case letter.
Problem is here:
// destination = "D:/Documents/NetBeansProjects/printing~subversion/fileupload/Uploaded/"; // main location for uploads (CHANGE THIS WHEN USING PREDATOR)
File theFile = new File(destination + "/" + username);
theFile.mkdirs();// will create a sub folder for each user (currently does not work, below hopefully is a solution) (DOES NOW WORK)
System.out.println("Completed Creation of folder");
NewDestination = destination + username + "/";
You have commented the destination variable and you are using here:
NewDestination = destination + username + "/";
I wonder whats the issue...I tested your code and it works fine...are you getting compilation error or runtime error?
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class Test1 {
/**
* #param args
*/
public static void main(String[] args) {
new Test1().loadProp();
}
Properties prop = new Properties();
public void loadProp() {
try {
prop.load(new FileInputStream("c:/Test/Computer.txt"));
System.out.println(prop.getProperty("destinationPDF"));
System.out.println(prop.getProperty("destination"));
System.out.println(prop.getProperty("fileList"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Output:
D:/Documents/NetBeansProjects/printing~subversion/fileupload/web/resources/pdf/
D:/Documents/NetBeansProjects/printing~subversion/fileupload/Uploaded/
D:/Documents/NetBeansProjects/printing~subversion/fileupload/web/resources/Directory Files/directoryFiles.txt
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();
}
}
.
.
.
}