Creating a properties file in Java and eclipse - java

I want to create a config.properties file, in which I want to store all the key and values instead of hard coding them in the Java code.
However, I do not know how to create a properties file in eclipse.
I researched and found help on how to read a properties file.
I need help with how to create it.
Here are my specific questions:
Can a config.properties file be created in eclipse, and data be
typed directly into it as though the config.properties is similar to
text editor?
If it can be directly created, the can you please let me know the
steps to create this properties file?
I am assuming that properties file can be created just like how java
project, java class etc are created (by right clicking at package or
project level). Is this correct assumption?
Or creating a properties file and adding data to it needs to be done
by java coding?
I will greatly appreciate any help.

Create a new file from file menu Or press Ctrl+N
In place of file name write config.properties then click finish
Then you can add properties your property file like this
dbpassword=password
database=localhost
dbuser=user
Example of loading properties
public class App {
public static void main(String[] args) {
Properties prop = new Properties();
InputStream input = null;
try {
input = new FileInputStream("config.properties");
// load a properties file
prop.load(input);
// get the property value and print it out
System.out.println(prop.getProperty("database"));
System.out.println(prop.getProperty("dbuser"));
System.out.println(prop.getProperty("dbpassword"));
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

Related

Unable to make getResourceAsStream() to load the .properties resource - using Netbeans IDE

First of, my sincere apologies for bringing up an oft repeated question in this forum; but I cannot figure out my mistake(s).
I have two .properties files that I am trying to load unsuccessfully. Here's the folder structure I have - unless there is a compelling reason otherwise or it is contrary to the best practice, I like to keep this structure:
As you notice my DAO code is under zencs.dbutils package and my .properties files are respectively under zencs.resources.properties.db* packages.
The reason I do it this way because eventually this will connect to and manage multiple data sources - my DAO code will evolve to handle them dynamically (not yet so). I want to set up all data source properties in one place
My Project properties are set as follows:
Now in my DAO class I have a method initProperties(), called by getConnection(), that is trying to reference these properties files through getResourceAsStream(). Please see below code that I tried:
public class DAO {
Connection conn = null;
public Properties properties = new Properties();
public Properties dbConnect = new Properties();
private void initProperties() {
InputStream inputDBdrivers = getClass().getResourceAsStream("snowflakeConnect.properties");
if (inputDBdrivers != null) {
try{
dbConnect.load(inputDBdrivers);
inputDBdrivers.close();
} catch(IOException ioex) {
System.err.println(ioex.getStackTrace().toString());
}
} else {
System.out.println("snowflakeConnect.properties file not found! Terminating Application normally...");
System.exit(0);
}
InputStream inputDBprops = getClass().getResourceAsStream("snowflake.properties");
if (inputDBprops != null) {
try{
properties.load(inputDBprops);
inputDBprops.close();
} catch(IOException ioex) {
System.err.println(ioex.getStackTrace().toString());
}
} else {
System.out.println("snowflake.properties file not found! Terminating Application normally...");
System.exit(0);
}
}
Connection getConnection() throws SQLException {
// build connection properties
initProperties();
try {
Class.forName(dbConnect.getProperty("driver"));
} catch (ClassNotFoundException cnfex) {
System.err.println("ERROR: getConnection() :: Snowflake Class not found: " + cnfex.getMessage());
}
return DriverManager.getConnection(dbConnect.getProperty("connectStr"), properties);
}
public DAO() {
try {
this.conn = getConnection();
} catch (SQLException sqlex) {
Logger.getLogger(DAO.class.getName()).log(Level.SEVERE, null, sqlex);
}
}
}
When I am executing it, the error says "snowflakeConnect.properties file not found! Terminating Application normally..."
My evaluation is that the code in the above form resolving the files to be in zencs/dbutils/ and the ClassLoader cannot find them there obviously.
I tried full absolute path (out of desperation though it expects relative); I tried relative path with "../resources/properties/{dbdrivers | dbutils}/filename.properties" with no success. With the relative path it is resolving to "zencs/dbutils/../resources/properties/dbdrivers/snowflakeConnect.properties" for ClassLoader...
Am I NOT setting the resources folder and everything underneath it correctly?
Obviously my comprehension of how it should resolve is flawed. Can you please help with what I might have not understood and how should I go about this issue?
Thanks a bunch!
You could try to use getResourceAsStream() including your package name like this:
InputStream inputDBdrivers = getClass().getResourceAsStream("/zencs/resources/properties/dbdrivers/snowflakeConnect.properties");
InputStream inputDBprops = getClass().getResourceAsStream("/zencs/resources/properties/dbutils/snowflake.properties");
The leading slash is usually the key part here. It could help to remove that as well but you said you've tried that already so I guess that's not what you're looking for.

write to properties file on specific line

Please let me know if this question has been asked before.
The Goal
In my android application when a user launches the App it loads the Login.class first. This class checks to see if a local file (in the included file path of the App) called app_prefs.prop exists (which it does) and then it checks the following fields structured like so:
username=
user_hash=
saved_email=
email_hash=
Those fields are blank by default just like so. I am reading them using the following code:
public static String getConfigValue(Context context, String name) {
Resources resources = context.getResources();
String TAG = "Retrieve";
try {
InputStream rawResource = resources.openRawResource(R.raw.app_prefs);
Properties properties = new Properties();
properties.load(rawResource);
return properties.getProperty(name);
} catch (Resources.NotFoundException e) {
Log.e(TAG, "Unable to find the config file: " + e.getMessage());
} catch (IOException e) {
Log.e(TAG, "Failed to open config file.");
}
return null;
}
If they return empty values, which by default they will, then the login screen is showed. If they do not, the login is attempted by default and if successful it will continue to the App, if not, login is shown again of course.
The Issue
When they sign in, I want to write the data into those fields. Currently its being sent to and from the server using JSON and works awesome. I am able to extract this data as well to a string variable which I am then passing to my save to config file after logging the user in but before continuing to the next App screen. This is where the problem lies, I have enabled the permission
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I have also passed all the values to it, but they are not being written to the lines I want them too. Here is the code I am using to write the file with:
private void commitUserInfotoFile(Context context, String username, String passhash, String rmemail, String rmemailhash) {
Resources resources = context.getResources();
String TAG = "Store";
try {
InputStream rawResource = resources.openRawResource(R.raw.app_prefs);
Properties properties = new Properties();
properties.load(rawResource);
//tried using setProperty as well as put but neither works
properties.setProperty("username", username);
properties.put("username", username);
properties.setProperty("user_hash", passhash);
properties.setProperty("saved_email", rmemail);
properties.setProperty("email_hash", rmemailhash);
Log.e(TAG, "Wrote the values to the stored file");
} catch (Resources.NotFoundException e) {
Log.e(TAG, "Unable to find the config file: " + e.getMessage());
} catch (IOException e) {
Log.e(TAG, "IO Exception loading file.");
}
}
Yet its not storing those values to the file even tho I get the message Wrote the values to the stored file in my console. I am a little confused as to the writing of properties using this method so any help would be appreciated. Thanks
You never store the result of your edits back into the resource. setProperty() just updates some internal key-value pair in the Properties object, it does not update it's source. You need to call Properties.store(OutputStream, String) when you are done with your edits. See here:
https://developer.android.com/reference/java/util/Properties.html#store(java.io.OutputStream, java.lang.String)

Why isn't my properties file updated in my Web App project?

I am trying to read and write a properties file with all my server and database connections in my JSF web application project in eclipse. Am using log4j to write to console. My config.properties file is:
dbserver=localhost
dbname=mydatabase;instance=myinstance
dbuser=myuser
dbpassword=mypassword
I placed my config.properties file in webapp/WEB-INF/classes folder (this is the classpath right?). I have verified that it is reading the file correctly in this specific location because if I delete the file, it breaks.
In my managed bean, I have functions to read and write to the config.properties file.
public void getSettings() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("config.properties");
Properties properties = new Properties();
try {
properties.load(input);
this.server = properties.getProperty("dbserver");
this.db = properties.getProperty("dbname");
this.user = properties.getProperty("dbuser");
this.pass = properties.getProperty("dbpassword");
logger.info("Config file successfully loaded!");
} catch (IOException e) {
logger.error("Loading Database Settings Error with " + e);
} finally {
if (input != null) {
try {
input.close();
logger.info("Closing config file...");
} catch (IOException e) {
logger.error("Error closing config file with " + e);
}
}
}
}
public void saveSettings() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Properties props = new Properties();
OutputStream out = null;
try {
props.setProperty("dbserver", this.server);
props.setProperty("dbname", this.db);
props.setProperty("dbuser", this.user);
props.setProperty("dbpassword", this.pass);
URL url = classLoader.getResource("config.properties");
File file = null;
try {
file = new File(url.toURI().getPath());
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// File f = new File("config.properties");
out = new FileOutputStream(file);
props.store(out, "This is an optional header comment string");
logger.info("Config file successfully saved!");
} catch (IOException io) {
logger.error("Saving configuration properties failed error with : " + io.getMessage());
} finally {
if (out != null) {
try {
logger.info("Closing config file...");
out.close();
} catch (IOException e) {
logger.error("Failed closing configuration properties file error with : " + e);
}
}
}
}
I never had an issue reading from the properties file but had a hard time writing to the file. This issue seemed to have been solved by specifying
URL url = classLoader.getResource("config.properties");
Now, if I change the server name from "localhost" to "192.168.1.1", I can see that the new information persists even though I refresh the page or restart the server. HOWEVER... when I open the config.properties file, I still see
dbserver=localhost
when I am expecting to see
dbserver=192.168.1.1
The information seems to persist somewhere else even though the file still remains the same? How and where can I access the contents of my properties fie to see the changes that are being made to it?
Modifying the WAR file is a bad idea (for example, some web servers may notice the file modification an redeploy your app, there may be problems when the server explodes the war on deployment etc.)
I would suggest applying an alternative approach - some possibilities are:
Place the properties in a database table, so they can be easily modified
Use an external properties file for overriding your "Property.prop" file settings. You can pull this off for example as follows. Assume that the default property values are bundled in your WAR and the modified values are saved to some other path, which is defined using a system property - let say it's called CONFIG_LOCATION. Now after loading your properties from the bundle you read them also from this external "overrides.prop" file - this overrides your defaults from "Property.prop":
PropertiesConfiguration pc1=new PropertiesConfiguration(a);
try(
FileReader propReader = new FileReader(System.getenv().get("CONFIG_FILES") +"/overrides.prop"){ pc1.load(propReader);
}
When you need to save changes, you do that to "overrides.prop" - this will save all the properties, not only the changed ones, but that should have no negative effects.

Reading properties from an XML file using Input Stream?

Currently within my Java Application I have the following Class that I use in order to retrieve values from my properties file (application.properties):
public class MyProperties {
private static Properties defaultProps = new Properties();
static {
try {
java.io.InputStream in= MyProperties.class.getClassLoader().getResourceAsStream("application.properties");
defaultProps.load(in);
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static String getProperty(String key) {
return defaultProps.getProperty(key);
}
}
An example of instantiating an int using the MyProperties class:
int maxNumberOfPeople = Integer.parseInt(MyProperties.getProperty("maximumPeople"));
I would like to change this class in order to read an XML properties file rather than e.g. application.Properties.
How can I do so, and still keep the ability to still instantiate values using the MyProperties class?
Read the javadoc for the Properties.loadFromXML(...) method.
Method summary:
Loads all of the properties represented by the XML document on the specified input stream into this properties table.
The Properties javadoc includes the DTD for the XML document (file).
It would be better to write your loader using a try-with-resources like this:
try (java.io.InputStream in = MyProperties.class.getClassLoader().
getResourceAsStream("application.properties")) {
// load properties
} catch (Exception e) {
e.printStackTrace();
}
Also, it is a bad idea to catch and squash exceptions like that.
Don't catch Exception.
If the properties failed to load, you most likely want the application to "bail out".
Finally, you probably shouldn't load the properties in a static initializer, because that leaves you with no clean way to deal with any exceptions that might arise.

jar file load html pages in JEditorPane

I'm trying to load html pages stored inside the jar file into a help JEditorPane. So far it works when I run it in eclipse but when i make a runnable jar it wont work, except if i put the map res/pages/... in the same map with the jar file
class HelpButtonHandler implements ActionListener{
#Override
public void actionPerformed(ActionEvent arg0) {
infodex = new JEditorPane();
helpDialog = new JDialog();
URL url1 = null;
try {
url1 = (new java.io.File("res/pages/help.html")).toURI().toURL();
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
infodex.setPage(url1);
} catch (IOException e) {
e.printStackTrace();
}
helpDialog.getContentPane().add(new JScrollPane(infodex));
helpDialog.setBounds(400,200,700,600);
helpDialog.show();
infodex.setEditable(false);
Hyperactive hyper = new Hyperactive();
infodex.addHyperlinkListener(hyper);
}
}
A file packaged inside a .jar is not a file on the file system. You cannot access it with the File class.
A file inside a .jar is called an application resource. You access it using the Class.getResource method:
url1 = HelpButtonHandler.class.getResource("/res/pages/help.html");
It is up to you to make sure the files are properly packaged in your .jar. If url1 is null, check the structure of your .jar file.
When you put resources in a jar, you cannot access them using File. You need to access them as a resource through the (more precisely: a) classloader. For example:
HelpButtonHandler.class.getResource("/res/pages/help.html");
Make sure you put the resource in the right place: if you leave out the first slash ('/'), the classloader will try to locate it relative to your class (which is usually not what you want).
use gerResource() method...
url = getClass().getClassLoader().getResource("res/pages/help.html");
check this link
http://oakgreen.blogspot.com/2011/12/java-getclassgetclassloadergetresourcem.html

Categories

Resources