file load in a jar - java

I'm loading a prop and saving it
File propfile=new File(getClass().getResource("credentials.properties").toURI());
prop.load(new FileInputStream(propfile));
prop.setProperty("a", username);
prop.setProperty("c", password);
prop.setProperty("b", pbKey);
prop.store(new FileOutputStream(propfile), null);
When i normally run this in netbeans its fine, when its bundled into .jar file it throws
Caused by: java.lang.IllegalArgumentException: URI is not hierarchical
at java.io.File.(Unknown Source)
now when i use
getClass().getResourceAsStream("credentials.properties");
i can read the file , but i can't save the file unless i use the .toURI()
as in -> Storing changes in .properties file that has been read via getClass().getResourceAsStream
so when i use toURI() and when i run it (jar file) it would cry out saying the URI is not hierarchical
and when i use getResourceAsStream , i couldn't save the file
what should i do?
the properties file is in same package as class is in.

If you only need to load the properties, you shouldn't be using File at all - you should use getResourceAsStream.
If you need to save the properties back again, you can't easily have them in a jar file. You'd need to rebuild the jar file each time you save - ick!
If you really need both, you might want to consider having a file which is created the first time you need to save changes: when loading, use the file if it's present, but use the version in the jar file otherwise.
EDIT: If you're building a desktop application and these are basically user preferences, you should look into the Preferences API. Also be very careful if you're storing passwords... avoid doing so if you possibly can.

Try:
File userFile = new File(System.getProperty("user.home"), "myProgram.properties");
if(userFile.exists()) {
prop.load(new FileInputStream(userFile));
} else {
prop.load(getClass().getResourceAsStream("credentials.properties"));
}
prop.setProperty("a", username);
prop.setProperty("c", password);
prop.setProperty("b", pbKey);
prop.store(new FileOutputStream(userFile), null);
(be aware that user.home does not work every time on every machine, but it should work next to every time.)

Related

Best way to distribute a Java app with resource files (DB connection parameters, images, ...)

I want to distribute a Java application that connects to an external database using a Java properties file. My issue is that once my project is exported as a Jar file (and then as an EXE using Launch4j) in a different place than my project's root folder, the connection to my database fails and most of my pictures are not loaded.
Regarding just the connection, I have tried several things to read the connection properties written in an external file, which is located in a source folder :
The code :
I also tried to let the property file in the root folder of my project: both way work when running the project, but fail when launching the jar or the exe.
First I thought it was just because of the exportation of my project, that maybe failed due to some wrong settings. But I am started to think that I may have a wrong understanding on how to import resources into a Java project, even thought I followed several topics on that subject on Stackoverflow.
So :
What is the best way to include properties files in a way that makes it possible to export them in a Jar/exe file ?
Or, should these files be included after generating the Jar, by referencing them when producing the exe ? How would that be ?
As the connection file contains some sensible data (ie. the password to connect to the database), I hoped there was an official way to keep that file protected from unwanted access after exporting the Jar/exe file.
Thank you a lot for helping.
I can provide more code and pictures if needed.
Resources (as in a jar) are not File (on the file system). Use
getClass().getResourceAsStream("/conf/connexxion.properties");`
For that place the conf under /resources.
String configFile = "conf/connexion.properties";
InputStream inputStream = this.class.getClassLoader().getResourceAsStream(configFile);
Properties props = new java.util.Properties();
if (inputStream != null) {
props.load(in);
}else{
System.out.println("File not found");
}
(or)
Properties prop = new Properties();
URL url = ClassLoader.getSystemResource("/conf/connexion.properties");
if (url != null)
prop.load(url.openStream());
}

Writing to properties file from .jar executable

I have a problem with writing to properties file via .jar file.
My 'output' works only in Eclipse, but don't know how to change it and make it works in executable .jar.
FileOutputStream output = new FileOutputStream("src/application/data.properties",true);
InputStream in = Login.class.getResourceAsStream("data.properties");
properties.load(in);
properties.setProperty(username+"Username", username);
properties.setProperty(username+"Password", password);
properties.store(output, formattedDate);
EDIT:
I'm getting no errors. I want to store this 'username' and 'password' in data.properties file which is included in a project. When I run it in Eclipse, it works. When I run it by .jar file, it doesn't write those data to properties file. I suppose, it's because when it creates 'output' while running jar, it is created only locally, and it doesn't provide me the access to appropriate file, but I might be wrong. I get this access and I can work on this existing file when I create 'in' by .getResourceAsStream(), but don't know how create 'output' in a similiar way, and be able to store data in already existing file in project.
I create .jar in eclipse by "Export -> runnable JAR file " and run it by double-click.
I'll risk a guess: getResourceAsStream is returning a Stream reading the properties file inside the JAR, while FileOutputStream is addressing a file outside the JAR - the properties inside the JAR is never changed!
It is not trivial to overwrite a file inside a (running) JAR! The Jar must be recreated for that. Probably better only write/read from an external file, that is, use FileInputStream instead of getResourceAsStream. It's also a bit strange to access a file in the "src" directory since this normally is not included in the deployed system/code.
Using FileOutputStream(..., true) is appending the data to the end of file - it is not overwriting the data for an existing user. Not sure if that is a problem or if this code is only called for new users?!
saving clear passwords (file or database) is a potential security threat...

how to read config.properties j2ee

I need to read in config.properties for some configuration.
I am open to any way of doing it, with requirements.
I want it outside my war file so that it can be changed easily, and does not require a rebuild.
I have searched everywhere but cannot find how to do it, I'm sure this is java 101, but I cant figure it.
I have tried classloader but that seems to only load resources from inside the war, and I cannot find how to get the location I loaded the war into my server from to read it from there.
I also cannot find a way to pass in an argument via command line parameter's as its a soap endpoint, which I can access anywhere in my code?
I saw this Where to place and how to read configuration resource files in servlet based application?
and i want to use the file system approach but I don't want a hard coded path for the config file.
I just want something simple and easy, I know there is something but I just cannot find it.
use this this is helpful your question . i think.
In one method abcd
public static String abcd(String one) {
properties = new Properties();
properties.load(<classNmae>.class.getClassLoader().getResourceAsStream("AppResources.properties"));
return properties.getProperty(one);
call this code
String fileLocation = abcd("internal property file");
Properties properties = new Properties();
FileInputStream fis = new FileInputStream(fileLocation );
properties.load(fis);
fis.close();
acd = (String)properties.get("acd");
Note:
AppResources.properties have external file location D:/aaa.properties file
then in second method you read properties of external file
I want it outside my war file so that it can be changed easily, and does not require a rebuild.
May not be how you want it, but just to answer this, we have a similar scenario where our web applications are deployed in web servers located in locations /apps/servers/webserver-1, /apps/servers/webserver-2. And we have properties placed in some other locations like /apps/my-web-app1/app.properties and /apps/my-web-app2/app.properties.
Now good thing about this structure is that if I need to update any property, I just do the edit in the relative property and restart my web server. A downside of this is that I have to pass in paths to these properties file as system arguments to my web-server startup scripts (in my case, these are the catalina.sh files, yes I am using tomcats).
So my catalina.sh has line somewhere lying around something like
export JAVA_ARGS `-Dpath.to.properties.of.my-web-app2=/apps/my-web-app2/app.properties` ....
To read these properties, I have a Property Utility function that gets called by the StartupServlets of each application. The purpose of this function is to simply open up this file by reading the system property path.to.properties.of.my-web-app2 and puts these properties in something like a cache (a HashMap in my case) from where I can access them easily throughout the application.

How to use a .properties file in Eclipse Java Dynamic Web Project?

I'm developing a Dynamic Web Project in Eclipse. I created a .properties file for store database details (Username, Password etc.). I added it by right clicking on the project and New -> File . I used the Java util package Properties class. But it does not working. I can not retrieve any property from the file. Here is the code I used,
Properties prop = new Properties();
try {
prop.load(new FileInputStream("database.properties"));
String db = prop.getProperty("database");
String userName = prop.getProperty("dbuser");
String password = prop.getProperty("dbpassword");
} catch (IOException ex) {
ex.printStackTrace();
}
Is there something wrong or Is there any particular place where I should put properties file.
What you did is correct, ie right clicking the project and new--file.You have to Put your properties where you start your jvm from. Please look into the attached image. The properties file is marked in red. Look if your properties file is also located something like this.
Also add this in your code to find out where to put your file:
System.out.println(new File(".").getAbsolutePath());
For more details please follow this link- FileNotFoundException when using java properties file
Normally, you make sure the properties file is in the project runtime classpath (e.g. WEB-INF/classes) and then load it using either the System classloader or the property file handler's classloader, i.e. (Freehand typing from memory -- NOT COMPILED)
try{
Properties p = new Properties();
InputStream in = MyPropertyHandler.getClass()
.getClassLoader()
.getResourceAsStream("com/package/props/database.properties");
p.load(in);
catch(IOException e){
e.printStackTrace(System.err);
}
I'm betting you aren't pointing at the correct location. Make sure you're properties file is in the correct place. Using that code, I believe it is looking for ${CURRENT_WORKING_DIR}/database.properties, which is the case of a web app in eclipse is WEB-INF/classes (i think).
You should instead be using the more portable java.util.Properties#load(InputStream) with the result of javax.servlet.ServletContext#getResourceAsStream(String).
Try to give absolute path or relative path to the proprty file, also check this propery file path has been add to source folders or not, if not it will not be copied to your classes folder. (Right cclick on project , check java build path under source tab.
You should have .properties file in same package as class that is using it.
Or better, read properties file with getResourceAsStream method (otherwise you can have some problem later when you'll have file in .war archive).
InputStream inputStream =
getClass().getClassLoader().getResourceAsStream("database.properties");

Using .properties file from Java console program

I have created a Java program to compare scripts saved as files in the version management tool to those loaded in our database. It's a simple program, runs through start to finish and outputs to the console when it finds a discrepancy. Now I want to load the database URL, username and password as well as the location of my files from a .properties file.
I did assume that if I put the file on the classpath it would be visible from my Java program:
Properties values = new Properties();
try
{
File checkPackages = new File("myfile.properties");
if(!checkPackages.exists()) throw new FileNotFoundException();
values.load(new FileReader(checkPackages));
}
catch(FileNotFoundException fnfe) {}
I also wanted to save this whole program to a .jar file so that it would be that bit more usable. Unfortunately, the only way I have found to reference the .properties file is to have it in the directory where I am running java.exe. The PATH or the CLASSPATH don't seem to apply??
I found an Oracle site about the .jar file's Manifest file as I was hoping there'd be an answer there, but the Class-path: element in the manifest only seems to refer to .jar files that are not in the .jar (and not .properties files that are!)
Questions:
Is there any way to wrap the .properties file into the .jar file so that my user doesn't have to know it is there?
Is there any way to wrap the Oracle driver .jar into the app's .jar so my user doesn't have to know it is there (Oracle says this needs 'custom code')?
TIA
You can get the resources in your classpath (even when sealed in the JAR) by using the ClassLoader#getResource() and ClassLoader#getResourceAsStream() methods.
For example:
Properties values = new Properties();
values.load(ThisClass.class.getClassLoader().getResourceAsStream("myproject.properties"));
// umm, don't forget to close the stream, this code is just an example usage
Note that storing the username and password to any database in a program is considered a heavy security risk.
One of the appraoch can be to 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 ... -Dmyproject.properties=/path/to/my.app.properties
my.package.App
Fetch the property in your code as mentioned here:
String propPath = System.getProperty( "myproject.properties" );
final Properties myProps;
final FileInputStream in = new FileInputStream( propPath );
try
{
myProps = Properties.load( in );
}
finally
{
in.close( );
}
Well, I would recommend to encrypt the sensitive data (username, password, url in this case) with public and private keys rather than hiding it. It is afterall not hard to deflate any jar file (which is essentially a zip format) and trace the .properties file

Categories