It describes editing the templates used to build the packages. When I looked into that I found nothing was easy to learn about any of that. It might be able to be done there but then again you are required to know things a common user of the tool should never be required to learn to use the tool. The kinda stuff that makes your head hurt.
Why? If that is a matter of updating assets, you can use the relative path.
Something like <my-app-path>/assets/whateverassetfile.jar, and if you canât write there because of permission issues, then you should warn the user.
I couldnât find a safe way to use relative paths when using Files.walkFileTree.
I went though every web page I could read on it and found no sure fire way to guarantee the path you want is the path you get.
Maybe someone with more skill can be assured they could write it in such a way but I do not feel comfortable enough with it to risk destroying a users machine.
I already nearly did it to mine in just testing things when using relative paths.
I used Files.walk here instead of Files.walkFileTree just to write a cleaner code, but the point is: wonât it give me the path it should give me? I didnât know it.
The thing is, this is just a windows shortcut equivalent to System.getProperty("user.home") + "AppData\Local", So youâre really using relative filepaths anyway.
There really is no standard absolute location on linux, as each distro (Ubuntu vs. Fedora vs. Arch, etc.) can (and often does) make their own choices here. Even if you focus on a specific flavor of linux, youâll need admin access to write to those locations.
Mac, the closest is /Applications which should also require admin access.
What if you do find an absolute path that you liked? Users can (and probably will) try to re-arrange to their own satisfaction, so you canât count on that either.
AOI has had to deal with this from before the time of protection domains, etc, so might be worth a review if @fbaâs solution does not work out.
I went back through the version history of the application that I work on. The code that I mentioned up-thread traces back to at least 2007, when we migrated version control from CVS. I donât have revision data from before then, but I believe that itâs probably been in place and running fine for nearly 20 years, with no issues traced back to it.
You can put it in a try block (We do) and if it fails, tell the user that theyâve gotten too creative with the location of the application. (And ask them to tell you where they put it. Iâd love to see something that can break this!)
It does not care where the application is launched from. It only cares where the .jar file is located.
To reduce scrolling, here it is again:
URL url = <yourApp>.class.getResource("/path/to/<yourApp>.class");
if (url.toString().startsWith("jar:"))
{
String furl = url.getFile();
furl = furl.substring(0, furl.indexOf('!'));
dir = new File(new URL(furl).getFile()).getParent();
if (!new File(dir).exists())
return <error>;
}
If you read that entire post, including comments, you will find that it is not that simple.
There are pitfalls with any method mentioned in that post and every answer has contradictory information. Nothing was conclusive to the point you could say yes, thats how you do it.
The only answer that seems to of had no negative response was the 4th down in the post but the real only drawback from his point of view as was mentioned here, you have to check that it doesnât throw a security exception. And in the end there still are caveats on how things could go wrong.
Then you see how much code it takes just to get that path.
That leave me thinking donât even go there.
Yes, but this is something that is absolute in its end value. I know I can use my expected values and if the user has messed with anything, I will still only affect where I expect things to be.
That doesnât bother me as much as recursively moving out of the parent directory accidentally due to some obscure thing you donât think can happen when using relative paths, and then it does.
What most Linux apps do is create a directory under the user home â usually with a name starting with a dot (".") to make it hidden â and then create/download any files the app needs in that directory. In doing so, it doesnât matter where your app is located or if it is on a place where the user needs admin rights or not, because youâre always using <user-home>/.myappname to whatever you need. Gradle does it (~/.gradle), the jME SDK does it (~/.jmonkeyplatform) and many other apps do it as well. You possibly have that kind of directory in your Windows APPDATA, depending on what kind of software you use. You can do something similar to put your config files, downloadable assets and other stuff in the userâs machine.
Rather than leave Linux and Mac out, I will supply them with the zipped app image. I configured the updater to work on both but the users of those systems will be required to install into their home directory and setup their own shortcut manually.
If they donât do that, the game client will fail so I feel comfortable with that. No harm can be done to their computer.
Seeing as windows controls 75% to 85% of the world market, and jpackage works 100% on windows, windows is fully supported.
I decided that rather than setting the updater to also update the jre, it would be better to just have the user download the latest release from the release page. Its trivial to check for versions and reject a login unless they update. On windows, all the user would need to do is just run the msi they download and it will uninstall the old version as part of the install/update process. I intend to keep the jre updates as far apart as possible, yearly at maximum, hopefully longer.
Discovered that since I was using a standard jar distribution for the updater, running scripts, the only reason it worked was I had java installed. You can add a second launcher using jpackage but unfortunately, it dumps certain critical files jpackage uses into the same directory as the main application and includes its jars on the class path of the updater. Thatâs fixable but you can only control the updater file locations, not where the jpackage built files are stored.
The only way I could fix it was use jpackage to build a jre for the updater and bundle it with app. This unfortunately adds 130 mb to the download but after thinking on it, thatâs trivial considering a full blown game would be 8gb or more.
Would be nice to have a little more control over jpackage, maybe that will come with time.
Bit of an update for any future users that come across this thread:
Iâve been doing some updates on the application build that I manage. The probe-code that Iâve listed in this thread does throw an exception on OSX, but our fallback is reliable:
The java property user.dir is set by the WorkingDirectory Dictionary Key in the JavaX portion of your Info.plist. This can be relative to the .app folder itself.
This stays consistent no matter where the user places the .app,
Also consistent no matter where the user launches from - menus, finder, or via terminal command.
So should be safe for things like the OPâs usecase.