Change working dir in Java Webstart - java

Is there a way to change working dir for JVM when running Java Webstart?
When i use system.setProperties("user.dir", newDir) it sets it(system.getProperties() shows it does) but ignores it.
Is this a limitation in Java Webstart to always use the working dir where i started the jnlp file?
I am using all permissions in the jnlp file.
Please help!
EDIT: Whatever i do now, my webstart always uses user.dir to save files. Frustrating!

I've had this question in the past myself, but I've always found that, in the end, I didn't need it. Why do I say this?
Because your java web start app is not like an executable run from Program Files. It doesn't even exist on your computer like most programs (it is broken up into a bunch of different files and reassembled by the JVM). Therefore, you cannot say that the program has its own directory to do what it needs.
But it doesn't need to. Here's why:
Java has the Preferences API to help when you need to store data. The under-workings of the Preferences API is as mysterious as JWS, thus they are really a perfect fit. Either way, if you need to write things to a file, you should check this API to see if it can meet your needs.
If you need to write files for the user, then prompting them and allowing them to choose the location obviously means you won't use your current working directory to read/write files.
If you need to serialize objects, you should just create a program directory using the user.home resource as #AndrewThompson suggested. This will be "your" directory and is as good (in fact, better) than a directory in Program Files (if you're running on Windows, as an example).
In conclusion, in all cases (that I've come across), there's no need to change your current working directory. If you need your own folder, create one in user.home (because you won't run into file permissions issues there).

..all my settings file i use is created in the user.dir.
There is the mistake. Put them in a sub-directory of user.home & the problem is solved.

In the hypothesis you really really need to divert user.dir property for Java WebStart execution, here is the only option I have found: set this system environment variable (so system wide):
_JAVA_OPTIONS="-Duser.dir=C:\Temp"
But care about it, this option is read and applied to any JVM executions.
Why was it required in my context ? Because Java WebStart ClassLoader was looking for any single resource (class, properties...) in user profile before getting it from jar files in cache. As the user profile has been moved to a network storage, application start up became terribly slow. I am still investigating Java sources to understand (and avoid) this behavior. So my applications work perfectly without setting user.dir but that was the only work-around for the performance issue we got at the moment.

The recommended way to pass runtime parameters or user specific setting is through the jnlp argument
<application-desc main-class=".....">
<argument>user.home</argument>
..............

Related

Java Best Practices for Config File Locations

In UNIX and its derivatives, application config files live under /etc/, whereas they live elsewhere on Windows and other systems. The philosophy behind java is "Write once, run everywhere" and an app ideally shouldn't have to care what OS it's on. But I want my application to load a config file on startup and I need to provide a path. Right now, I'm loading different file locations switching off of the OS name, but this doesn't feel like it's best practices for Java. How do I reconcile this?
When I am making a game/app I just put a resources folder in the same path as the app. For example in the code, the directory would be "res/config.yml". In the same folder as the jar you put the resource folder named "res". you then put the file in the res file. So the app should get the file.
I usually put configuration files in a directory .<appName> (note the leading dot) in the user home, which is read at runtime via System.getProperty("user.home"). This is the expected location for Linux users, while on Windows it feels a bit exotic (compared with profile directories like AppData/Local or AppData/Roaming) even if it's an extremely popular choice for cross-platform tools. Using the current user's home means you won't usually have troubles with filesystem access rights, and using user.home is preferred instead of a custom property because it's provided out of the box by the system (and still it can be overridden)
Another approach is using the installation directory, but then you have to use an environment variable that points to that, like $APP_HOME, because it can't generally be inferred while the application is running (actually you can get the installation directory pretty easily for typical JAR deployments by playing with URLs returned by the main ClassLoader, but I consider it a hack and think it shouldn't be used). Your application can read the variable with System.getenv("APP_HOME"), and this variable must be set by the platform-dependent scripts you provide to start your application. This strategy has the downside that the current user may not have the rights to read/write to the named directory.
In our application we use different locations for configuration on each OS.
On Linux
/etc/applicationname
On Windows
[Use Selected Install Dir]/conf
We control where the application looks via a system property
-Dconf.dir=path
I don't necessarily think there is a correct answer in this case.

How can I set my Java applet's working directory in IDEA?

I have been using IntelliJ for a while now and I'm enjoying its suite of features but I'm having a hard time getting the run configurations to work for a java applet. I have a pre-existing Java tool that uses Swing and I'm using the JApplet class to load those GUI objects as an applet. The problem is I have a couple configuration files that I need loaded. I load these from the working directory and from my knowledge, this working directory would normally be the directory in which the applet resides. I think the major problem is IDEA sets the startup variable:
-Didea.launcher.bin.path=IDEA_BIN_DIR
I would like to be able to change this but I am seemingly unable to. I have tried overriding this flag by editing the applets run configuration VM parameters, but IDEA will continue putting the above one in even if I specify something different.
So in short, I'm having a hard time loading a local configuration file because I can't set the working directory for the run configuration in IDEA. Does anyone know how to get around this or know of a better way of running Java applets that use configuration files, in IDEA?
An applet normally runs in a sandbox in a browser, and such an applet can't access the local computer's file system, for security reasons.
Thus it is generally a bad idea to load configuration files from the file system, and "working directory" is not a useful term for an applet.
If these files change seldom (i.e. in principle only by the developer), you can put them to the applet's class files (i.e. in the jar file, or during development in the directory where the classes will be generated), and use class.getResource() or .getResourceAsStream() to load them.
If the configuration files should be definable by the webmaster, put them on the webserver - either at some fixed location relative to getCodeBase() or .getDocumentBase(), or specify them as parameters to your applet tag in the HTML tag.
If these are user specific configuration files (which the applet should be able to write), you either need to store them on the server and retrieve/store after a login (i.e. you need some logic at the server side), or you would store them at the client side.
The current way to do this would be using the JNLP API (in javax.jnlp.*) - there are some interfaces allowing Persistence, or loading/storing data (with the user having a FileChooser). Alternatively, you could sign your applet and request an AllPermission from the user - then you can access the file system.
Sorry, nothing of these answers your original question (I don't use IDEA), but maybe these help you to find another way.

Windows Mobile: automatically copy files on reboot

I have a Java app that runs on a Windows mobile device. At startup the app talks to our server to see if any files need updating and downloads them if they do. If any of the files are dlls they need to be stored in a temp directory and the device is rebooted because they might be currently in use. When the app starts it reads an xml file that lists all of the temp files and where they need to go and copies them into place.
A new requirement has come up that involves also updating the JVM files as part of this process. Since the code that does the copying is run on the JVM there is no way to do it since the files will always be in use. So we are looking at writing something in native code to do this copying process.
Before we start, I was just wondering if anyone knew of an already existing application or technique that does this (someone suggested a registry entry that tells the device to copy files on startup for example). Basically the requirement is to read some sort of configuration file that details the location of the source file and the destination then performs the copy. Any ideas before I reinvent the wheel by writing an app myself?
If your target handsets are handheld barcode scanners (Symbol, Intermec, etc.) they already have a framework in place for this. I don't have all the details, but I know from previous projects that they have a "protected" memory location that allows application to essentially re-configure / copy themselves from hard boots and similar problems. It might be worth seeing if any of that would work on your existing targets.
The scanners use either Windows CE or Windows Mobile.
In the absence of another answer, I have written a simple app to do it and put it in the startup directory. Was pretty easy, just didn't want to reinvent the wheel.
You can also rename your running executable file by the running-application itself. After this you can copy the file into the directory and simply restart your application.

Cross-platform way to ask for the user's documents folder?

I'm writing a cross-platform program in Java and want to stick the configuration files in the user's documents folder ("My Documents" under Windows, "Documents" under appropriate Linux, and whatever the folder's called under Mac OS), but I'm not sure how to ask Java for that.
I'd like to stay away from hard-coding things (do X if we're on Windows, Y if we're on Linux, or Z if we're on OS X), as this puts the burden of support on my shoulders rather than the Oracle development team.
I've checked the system properties list, but it doesn't seem to include the user's documents folder.
Sadly there is no easy cross-platform way. You will have to take advantage of native functionality on each OS platform
Here is some info on how to do it in osx
Here is some info on how to do it in windows
For Linux I don't have a convenient link, but given that there isn't necessarily the concept of a Documents folder in Linux, I don't know of a good solution. The system property user.home should at least be valid in Linux.
Partial solution:
boolean isMac = System.getProperty("os.name").equals("Mac OS X");
Or use http://commons.apache.org/vfs/ to get the operating system:
http://commons.apache.org/vfs/apidocs/org/apache/commons/vfs2/util/Os.html
// the folder name is the same whatever the language of Mac OSX.
Mac: System.getProperty("user.home")+File.separator+"Documents");
/Users/david/Documents
Win: System.getenv("APPDATA"));
C:\Documents and Settings\david\Application Data
This is usually not possible in a generic way. You will have to use platform dependent apstractions. I do it like this for AppData e.g., on Windows I detect the AppData/Roaming or AppData/Local, depending on the data I need to store, on other Platforms I create a folder ".myappname" in the userhome, and use this.
For the documents folder, you will have to read the registry. Before Windows Vista using the user.home propery + "/Documents" is not enought, because in other languages it might be "/Dokumente" (german) or something else. Just the registry has the real path to this folder.
On linux platforms it depends on the Desktop environment. You will just have to try it out. Gnome and KDE use different places to store the Documents folder, IMHO. And if you just use FVWM there, there is no predefined place for docs except the user.home property, what is a good fallback.
Assuming this is an application which requires installation, Why not ask the user to specify the location during installation. Generate a run script using this information which would set the appropriate environment variables. As a norm the user is not expected to run the java command!
When the user starts the application using this run script, the application can read the environment variables.
Alternatively, create a jar file with configuration files. Read the config files using Classloader's getResourceAsStream. As long as the configuration jar is under the classpath you can access the files. This also has the added advantage of hiding the configuration from accidental modification. This should work for folders as well (if the config needs to be modified by the user).
Ask the user, somehow, where they want to save data to, or use the current directory (simple relative paths) and provide appropriate instructions for set up. One means of "asking" is having a property that can be set via the command line.
Don't just pollute the user's home directory with your application's stuff - how do you know how they like their document tree organized?
I am absolutely fed up with *nix oriented programs dropping their little config files and data folders into the root of my documents folder.
What is wrong with hardcoding a way to get the path depending on the users operating system?
There can be large variances and OS's work differently with different names.
Simply on launch find the path of the documents folder based on their OS and continue to reference that path wherever it is needed.

Saving user settings/database/cache... in Java (On every OS)

My Java application is saving stuff in 'user.home' but on windows this does not seem to be the correct path to save application information (as a friend told me). An other option is using the preferences api but it's not possible to set up the hsqldb location using the preferences api. Also, I want all files to be available in the same folder (local database, config, cache, ...).
I'm looking for some example code or a framework that takes care of os-specific stuff.
On my WinXP Pro SP3 system, user.home points to C:\Documents and settings\<username>
Lot of applications just store their data there (instead of this path + Application data, but some others go down to there), creating a directory in Unix style, ie. dot + application name (examples: .antexplorer, .sqlworkbench, .squirrel-sql, .SunDownloadManager, .p4qt, .gimp-2.4, etc.).
Looks like a decent, common practice...
It's unusual for a window app to save data in user.home but not "wrong". Windows applications love to spread their data all over the place (a bit in the registry, a bit in the application's install directory, a bit in the Windows directory, a bit in System32, a bit here and a bit there). In the end, this makes it impossible to cleanly backup or remove something which results in the famous "Windows rot" (i.e. you have to reinstall every few months).
Anyway. If you really don't want to use user.home (and I see no reason not to), use code like this from Apache commons-lang to figure out if you're running on Windows. If this yields true, pop up a directory selection dialog where the user can specify where they want to save their data.
Save this information in Preferences and use this path the next time when your app is started. This way, users can specify where they want their data and you only have to leave one bit of information in the prefs.
For an application "foo" I'd create a directory named ".foo" inside user.home. For Windows it will look slightly strange, but almost noone ever looks in that directory (and it's filled with obscure directories anyway) and on Linux/Solaris/... it will result in a hidden directory that doesn't clutter the users home directory visually.
dynamically read (from your code) the value of APPDATA environment variable, and store your config files in %APPDATA%\\.myapp\config
==> value is platform dependent, do not use any hard-coded paths, always read the env. var.
The problem is not Wiindows but the standard java setup.
Long Discussion
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4787931>Here
I would advise picking this up on a '-D MYLOC=%USERPROFILE%' property on the command line.
Note that you will only get a "USERPROFILE" if the user did a desktop login, this does not get set if the user logged in remotly with citrix or similar or via ssh, also, coprporate desktops mess around with this setting and may set it to something unusable.

Categories