distributing my java app, HOW do I manage directories - java

My java applications is almost complete and now I am giving it a finishing touch. Although certain code requires to read data from specific directories on the computer. On my machine I did it in the following way:
FileOutputStream fos=new FileOutputStream(C:/User/AnirudhVarma/Document/Appname/foldername/file,true);
But on the users machine how do I ensure that it creates it in the following directory?
C:/enduser/appname/folder/file

Hard coding folder structure in code is very bad idea.
One way to handle this is:
You need to have a properties file something like that where user need to enter path to required folder. Mention this as requirement in install docs.
In your code you need to make sure folder has required content before proceeding. If not valid folder, just show error message with proper information to setup the directory path.

System.getProperty("user.dir") will return C:/User/AnirudhVarma on you machine. From there, I'd suggest you need to consider the platform. Under windows, you should store this kind of information into the AppData folder.
So you would end up with something like System.getProperty("user.dir") + File.seperator + "AppData/Appname/foldername/file"
Under MacOS, I believe the convention is to use .AppName instead, something like System.getProperty("user.dir") + File.seperator + ".Appname/foldername/file"

Related

System.getProperty("user.dir") alternative

I would like to write JSon files in my Java Application, it works perfectly in my IDE but as soon as I move the directory, the system fails to write the file. I eventually found the problem : The line System.getProperty("user.dir") returns a bad path.
The files are located in C:\wamp\www\myProject during development. Here is my code at the moment :
String url = System.getProperty("user.dir") + "\\src\\json\\Crc.json";
//Returns "C:\wamp\www\myProject\src\json\Crc.json"
After moving my project to C:\Users\myUser\Desktop :
String url = System.getProperty("user.dir") + "\\src\\json\\Crc.json";
//Returns "C:\Users\myUser\src\json\Crc.json"
I would like to have a way to find where my project directory is on the computer at anytime. Do you guys have a solution ?
The C:\wamp\www\myProject folder is just a random place on your hard disk.
Java supports 3 generic places to look for resources:
the current working directory. this is where your command prompt is and what System.getProperty("user.dir") returns, but you cannot rely on that beeing somehow related to any cretain place in the file system, especially not related to the project structure on your own system.
You should only use that if your program has a command line interface and looks for some default file name to work with.
the user home This is what you get when calling System.getProperty("user.home"). On Unix this resoves to $HOME and on Windows to %USERPROFILE%.
This is the best place for files changed at runtime or holding user specific content.
the own code location. Resources in the same package as your class are accessed with getClass().getResource("filenameWithoutPath") But usually you place resources in a special folder in the application root and access it like this: getClass().getResource("/relative/path/from/src/root/filenameWithoutPath").
In your IDE this special folder should be Project/src/main/resources (according to the maven Standard Directory Layout
This is appropriate for some global configurations that you change when creating the delivery package.

How to make File Reading Platform Independent in Java

Hi I am using Maven for Selenium automation tests using Java. I am using Excel Sheet to read data for filling up a registration form. Now It is a normal Maven archetype.
src
--main
--java
--mypackage for coding goes here.
--resources
--data
-- the excel sheet
--test
-- some stuff here under java
currently if I want to read a file I am writing src/main/resources/data/theexcelsheet.xlsx
but when I share this jar, I think this will break and I don't want this to break if I package this jar.
How do I make it platform or format independent.
I am using APACHE POI Api if you are thinking how I am reading files.
Someone reading gave me idea that I might be able to use MANIFEST files to do this but I am not sure, can someone help?
If you use getResource() to point to your file, the syntax of the path always uses / to separate the components, never \ so you do not have to worry.
In general, outside of a jar, for example if you want to save application settings in a folder, you have to use a OS specific separator - you can obtain it this way:
System.out.println("my" + File.separator + "dir");
Returns my\dir on Win and my/dir on Linux
Of course, that's not enough as you cannot use hardcoded paths like the "c:" drive, but you can get the most common paths reading the System class properties, eg:
System.out.println(System.getProperty("user.home"));
returns C:\Users\piero in Windows7 and /home/piero in Linux

Read File on Networkshare

I am running my Application from a network-share. For example: "\server\startProgramm.bat"
The Code in my startProgramm.bat:
java -jar %~dp0\app.jar
I need to open some config files. It is working local if i try to open them with:
new File("").getAbsolutePath() + "\\" + filename
but not on my Network share.
The config-files are in a subdir of the dir where my jar and bat files are.
new File("\\\\servername\\sharedDirectoryOnServer\\fileOnServer");
"Ok, this worked, but is there something like CurrentWorkDir?"
The current working directory is (by default) the one your program runs in. You can not change it within java (see here:
Changing the current working directory in Java?
),
the best practice is to just concatenate the server-path and file-name; but i think (not sure) it is also possible to start your program from the server (java \\server\\path\\myprog where there's a myprog.class in that directory) and make the working directory default to that path.

File paths in Java (Linux)

I have created a Java application that loads some configurations from a file conf.properties which is placed in src/ folder.
When I run this application on Windows, it works perfectly. However when I try to run it on Linux, it throws this error:
java.io.FileNotFoundException: src/conf.properties (No such file or directory)
If you've packaged your application to a jar file, which in turn contains the properties file, you should use the method below. This is the standard way when distributing Java-programs.
URL pUrl = this.getClass().getResource("/path/in/jar/to/file.properties");
Properties p = new Properties();
p.load(pUrl.openStream());
The / in the path points to the root directory in the jar file.
Instead of
String PROP_FILENAME="src/conf.properties";
use
String PROP_FILENAME="src" + File.separator + "conf.properties";
Check the API for more detail: http://java.sun.com/j2se/1.5.0/docs/api/java/io/File.html
I would also check what your current working directory is if your path to that file is relative. You just need to make a File test = new File("."); and then print that files canonical path name.
If you are referencing any other locations like user.dir or something to that effect by using System.getProperty(), you'll want to at least verify that the directory you are using as the relative root is where you think it is.
Also, as Myles noted, check the slashes used as file path separators. Although you can always use the "/" and it works.
And if you are referencing the path absolutely, you'll have trouble going between one OS and another if you do something silly like hard-code the locations.
What you want to do is check out System.getProperties() and look for file.separator. The static File.pathSeprator will also get you there.
This will allow you to build a path that is native for whatever system you're running on.
(If indeed that is the problem. Sometimes I like to get the current directory just to make sure the directory I think I'm running in is the directory I'm really running in.)
Check your permissions. If you (or rather, the user that the Java process is running under) doesn't have appropriate permissions to read the file, for example, you would get this error message.
This is a typical Windows -> Linux migration problem. What does ls -l src/conf.properties show when run from a prompt?
Additionally, check capitalisation. Windows isn't case-sensitive, so if the file was actually called e.g. CONF.properties it would still be found, whereas the two would be considered different files on Linux.
You should check the working directory of your application. Perhaps it is not the one you assume and that's why 'src' directory is not present.
An easy check for this is to try the absolute path (only for debugging!).
I would check your slashes, windows often uses '\' vs linux's '/' for file paths.
EDIT: Since your path looks fine, maybe file permissions or executing path of the app is different?
check your slashes and colons
in my case i set my PS1 to following value
PS1='\n[\e[1;32m]$SYSNAME(\u)#[\e[1;33m]\w [\e[1;36m](\d \T) [!]\e[0m]\n\$ '
i am trying to read from the env .such as system.getenv
Java was throwing exception
java.lang.IllegalArgumentException: Malformed \uxxxx encoding
Try the double slash, after doing things in JBoss I often had to refactor my code to use the double slashes

How to create an .INI file to store some settings in Java?

I want to create an ini file to store some settings for my application. Is it a good idea to find where the jar file is located and create an ini file there? If yes, then how can I find the location of the jar file?
But if you know a better solution for something like this, I would like to hear some of them.
EDIT: I'm using mac and I want to run the same application in windows. I could write something in the System.getProperty("user.home") directory, but I want to keep the system clean, if the user decides to remove the app. There is no a better way to store the settings file, for example in the same directory with the application?
You can locate your application directory using the ClassLoader. See: Java: finding the application directory. Rather than an .INI file, use a .properties file - you can load and save this via the Properties class.
As others have noted, you should not write user settings to your application directory. What if the user does not have write access to the application directory? What if your application is being used by multiple users on the same system at the same time? Neither of these situations are unusual, even on Windows.
You might still want to load some settings from the application directory - perhaps the administrator has configured default settings there.
A common convention is to save user settings to the user's home directory:
/home/user/.eclipse
C:\Documents and Settings\User\.eclipse
Although this means you might leave stray files behind, this can be beneficial if the user re-installs the app. Document such things in a README. Here is how to create and get a reference to the directory:
public static File getSettingsDirectory() {
String userHome = System.getProperty("user.home");
if(userHome == null) {
throw new IllegalStateException("user.home==null");
}
File home = new File(userHome);
File settingsDirectory = new File(home, ".myappdir");
if(!settingsDirectory.exists()) {
if(!settingsDirectory.mkdir()) {
throw new IllegalStateException(settingsDirectory.toString());
}
}
return settingsDirectory;
}
On unix-like operating systems, starting the directory name with a period (".myappdir") will make the directory hidden. On Windows, it will be located below My Documents, so users will not see the directory unless they go looking for it.
If the settings are only written by your application (rather than edited manually), consider using the Preferences API.
You should not be storing temp files in the install directory of an application. Remember, the user running the application may not have write access to that directory. The safest place to put stuff like that is in C:\Documents and Settings\username\Application Data\ApplicationName folder (adjusting the name as necessary).
That said, however, I would probably store that type of stuff in the registry instead of a file on their computer. (But, that's just me.)
Typically Java programmers don't use .ini files, but .properties files (different format). You can use the java.lang.Properties class as a nice programmatic wrapper if you do.
While you can get the location of your jar file by calling getProtectionDomain().getCodeSource().getLocation() on your class's .class member, I do not recommend that you do this.
I would instead write the file to the System.getProperty("user.home") directory - the users' home directory, or if it is truly temporary, System.getProperty("java.io.tmpdir")
It depends whether your ini needs to be human readable/writable under normal circumstances. If not, you can use a properties file rather than an ini file, and store it in the "user" directory.
As for finding the jar file, you would have to find the ClassLoader for a class known to be loaded from the jar, check that it was the appropriate type of ClassLoader (ie that it's really been loaded from a jar), and you can extract the path from that. I can probably dig out the code to do this if that's really what you want. I wouldn't necessarily recommend it.
EDIT The user.home property will give you the user directory, which you can safely use.
The idea with the .properties file instead of the INI file is good. Also, if you store some sensitive data in there, you may consider encrypting it. Check this out:
https://www.owasp.org/index.php/How_to_encrypt_a_properties_file
or this:
encrypt and decrypt property file value in java

Categories

Resources