Java - where to put application data? - java

I'm writing a Java application which requires a number of resource files (there will be about 100 files of 20-40K each). They are not edited by the user, but will require periodic updates (the application will have a function to check for changes to the resource files and download them). Ideally, the application should be cross-platform.
Allowing write access to a subdirectory of the program directory is generally frowned upon. If I was doing it as a Windows application I might put them in Application Data, but that's not going to fly cross-platform. What would be the best place to put them?

I would typically create a directory (name starting with a period ".") in user's home directory (System.getProperty("user.home") if I am not mistaken) and use that for application specific storage. Alternatively, you could take the directory name from user at the time of application installation.

Have a directory you use to keep these files in. Put that information in a properties configuration file. When you start up load the configuration file from your application install directory. From that properties file it tells you where to find your file directory. When your installer runs it can write out this configuration file for the platform you are installing on, and that can be OS specific.

Provide a configurable location, but default to a directory in the user's home directory, or in an OS-specific location.
You'll have to deal with this in a platform-specific way no matter what. You have a few options under OS X, though. For unix-like systems either a home directory, or perhaps something under /var.
That said, I don't believe a program managing its own data in its own directory is a bad thing; consider a program with an embedded database or similar. It's much more reliable to use an app home directory.

Related

Installable desktop application in java with desktop integration

I need some open source and cross platform framework/tool/library which provides functionalitites commonly available to native desktop applications, for example:
A user-friendly way to install the application
Finding out user's home directory
Finding out directory for persistent storage for files and configuration (can be different from home directory)
Finding out a suitable temporary directory for temporary storage of files
Starting a component in background when user logs in
Ability to open files with corresponding default programs
Does one exist?
I have used IzPack sometimes back. It's pretty good.

Uploading Files on Heroku

I have a Java Servlet/JSP application which requires the user to upload an archive file (either .rar or .zip). This archive file is then extracted, and the extracted files are parsed. After parsing the files, the data in them is added to the database and the files are deleted again.
On my local machine, this works perfectly, since you just use the filesystem provided by the OS. But now I'd like to run this application on Heroku and I'm unsure on how to do the file uploads.
Since these files are user specific, and not permanent, my initial thoughts were that I could just use the ephemeral file system provided by Heroku and I do not require the use of S3.
At the moment, my application runs on only 1 web dyno and no worker dyno's but in the future this may get scaled to multiple web dyno's, depending on the amount of users that are going to use it.
Can I use the ephemeral file system for my specific use case, and will it scale properly?
I am currently writing using ServletFileUpload, and am writing to java.io.File; Can I just change the path of my java.io.File to a path in the ephemeral file system? What would be an example of such path?
I guess you can use the ephemeral fileystem in your specific case, as it's just a temporary usage for parsing the file.
You can use the /tmp directory but keep in mind that the file will be destroyed after the request is complete.
This is discussed in this post https://stackoverflow.com/a/12416923/476782

Common place for creating files on various platforms (non-user-specific)

I write cross-platform java app and I need some place where I can store some amount of files. These files will be used by another java application that may run under another user. This mean that I cannot use:
System.getProperty("user.home");
since I may have no permissions to read/write these files. What I need is some way to get non-user-specific folder where every app can create/read/delete files (something like "C:\ProgramData" for windows).
Is there a cross-platform way to get such folder(at least for Windows and Linux), or if there is no any - what is the best way to get such folders for Windows(should work on XP-7), Linux and Android.
Any pieces of puzzle are welcomed.
I'm not aware of such such a cross-platform folder which is additionally readable by all users. But you can:
Define a specific folder for each OS, commons-lang may help you determining the platform (see SystemUtils)
Check if the folder read/writeable for the current user during application start-up.
Using a central configuration (where the data exchange folder is defined for this installation) may also be an option, but this depends on the packaging of your project.

is it possible to place a myfile.file in C:/Windows/System32/ location at runtime?

I wish to place a file named as myFile.file in
C:/Windows/System32/ location.
Here is use java code to place my file. while I execute my program it throws "Access Denied:C:/Windows/System32/myFile.file".
why is it happening? Is it possible to place in that location?
That (and many other) system locations are restricted for admin users/elevated applications.
Application data should be stored in the user application data files in the user profile (or the common application data).
If you really must write into the system folder, then you will need to ask the user for permission via UAC, either by using ShellExecute() with the runas verb to run another program, or COM elevation (if that's possible in Java)
Update
See Andrew's answer for a method to get the correct path in Java.
Put myFile.file in a sub-directory of user.home.
The sub-directory could be the package name of the class saving the file. E.G. if your main class is our.com.Main, store the file at ${user.home}/our/com/myFile.file. The reason to use a sub-directory is to help prevent another apps. myFile.file from overwriting or interfering with your own version.
To get the location of user.home, see:
System.getProperty("user.home");
The value of user.home here, is:
Name Value
user.home C:\Users\Andrew
This technique will work reliably for Mac. & *nix, as well as Windows.

How make working directory files available to WebStart application?

We have to make a Java application demo available on Internet using JWS. It goes pretty well; all that's missing is making working directory files available for the application.
We know about the getResource() way... The problem is that we have different plugins for the same application and each one require different files (and often different versions of the same files) in their working directory to work properly. So we just change the working directory when we want the application to have a different behavior.
Currently, the demo is packaged in a signed jar file and it loads correctly until it requires a file from the working directory. Obviously, the Internet users of this demo don't have the files ready. We need a way to make these files available to the WebStart application (read/write access) in its working directory.
We've thought of some things, like having the application download the files itself when it starts, or package them in the jar and extract them on startup.
Looking for advices and/or new ideas. I'll continue working on this... I'll update if I ever find something reliable.
Thank you very much!
I said I would share what I found in my research for something that would fit my needs. Here's what I have so far.
I have found that the concept of current working directory (CWD) does not really make sense in the context of a Java Web Start (JWS) application. This had for effect that I stopped trying to find the CWD of a JWS and started looking for other options.
I have found that (no, I didn't know that) you can refer (using getResource()) to a file in the root directory of a JAR file by simply adding a '/' in front of its name. ("/log4j.properties", for example.) The impact of this is that I can now take any file which is only referred to in a read-only manner in the root of that JAR file (which is really only a ZIP file). You can refer to any file in the root of the JAR file using AnyClass.class.getResourceAsStream. That rules out the problem with read-only files required to run the application, at the cost of a switch in the code telling whether the application is run from a valid CWD or from a JWS context. (You can very simply set a property in the JNLP file of the JWS application and check if that property is set or not to know where to look for the file.)
For write-only files (log files in my case), I used the property , adding a directory with the name of the application: <user.home>/.appname and added log files to it.
Read/write files (which I don't have in my case) would probably simply go at the same place than write-only files. The software could deal with uploading them somewhere if needed, once modified, I guess.
That's the way I deal with the problem for now.
Note there is a service you can explicitly ask for, to get file access to the computer (unless you go all the way and ask for full access (which requires signed jar files)).
Then you need to determine where these files need to go - basically you have no idea what is where and whether you may actually write anywhere. You can create tmp-files but those go away.
Would a file system abstraction talking to the JNLP-server do so you store the users data on the server?

Categories

Resources