Overwrite a jar while in use - Java - java

I have jar client that has an auto updater built in, when you open it if there is a new version it will download it. I made it so it downloads the new version to the same directory that the user is running the current one from so that it's easy for the end user.
The problem with this is that it can't overwrite itself because it's in use obviously. As of right now it downloads a new version and I have the version in the name so it downloads a new one with like v1.1 or v1.2 in the jar name.
This works but just seems to messy in my opinion, does anyone know of a way to make it so I can just always have the same file name? IE does anyone know of a way to overwrite a file that's in use, or a work around that will close the current and replace then reopen the new one?
Here is my downloader class - http://pastebin.com/KJdDndhh

I think the best solution to this problem is to not have 1 Jar file both manage itself as the application and the updater. Have a separate Jar for updating and your current one act as the application alone.
This seems to be similar to how many applications with auto updating works.
League of Legends has a separate updater that runs before the main application launches
Antivirus usually loads their signature files into memory and close their connection to them allowing them to overwrite those files.

When a JRE executes a JAR file, it loads the classes it needs and then releases the JAR file. So you will be able to overwrite the JAR file even from the code within the JAR file.
I have implemented the same update mechanism and it works fine for me on Windows 7, Ubuntu and Mac OS.
But if it's not able to overwrite for you, then from your code you are probably using up some resource which it has to keep the lock on (I am not really sure what, it's just my guess).

Related

How to make a .plist for a mac applications

I'm trying to turn a java program into a mac .app file, or more accurately, a native mac application. This requires a .plist file (see here) but I can't seem to find anywhere that works in telling me how to make one. I set up the directories as they specified, and my application debugs properly. Its just every time I try to open the application, it immediately shuts down. Does anyone know how to make a (minimalist even, for now) working plist file?
Right click on your project and select Export. Assuming you on using a Mac, there will be an option to output an application bundle.
Once you have created the app bundle (which itself is just a directory), go here to find the Info.plist file:
MyApp.app/Contents/Info.plist
From there you can edit the plist, if you need to.

Packaging external files with JavaFX deployment

I have a JavaFX app that reads in a configuration file. I'd like the config file to remain outside of the jar to facilitate modification without recompiling. Is there a way to set up netbeans to grab the config file and include it in the installer?
I've found the option to change to icon and that works fine but I haven't been able to discover how to tell it to also include specific external resources.
I've read the information posted here: http://docs.oracle.com/javafx/2/deployment/self-contained-packaging.htm but I'm still not seeing a way to accomplish this.
I don't think there's a way to do this (though I may be wrong). I needed something similar to this once, and the approach I took was
Package the file in the jar file
At program start-up time, check to see if the file exists in the expected location on the local drive
If it's there, read it, etc
Otherwise, read the contents from the jar and write them to the expected file
This solves the problem of "deploying outside the jar", and it also solves the problem of the user inadvertently deleting the file after deployment, etc.
The way I solved this issue (due to having many dependent .dll's and other type items) was to use netbeans to compile the jar, which has things like images/css/fxml etc. etc. and then use an Inno Script to actually compile and configure the installer, since inno makes it pretty straightforward to include extra resources. I have yet to find a way to do this properly within javafx itself.

How to delete a executing jar file

I have created an application, in which based on an operation, it modifies the properties file inside the jar.
I'm able to create a new temp jar with the updated changes. But can't rename the jar file to the existing jar file name. Since it is running, I am not able to delete and rename it.
Can any one suggest any operations or suggestions to delete the jar (Currently Executing) and rename the temp jar to that name?
I have doing for the Application:
http://java.net/projects_tags/jeazyprops
You're problem is the default ClassLoader that pre-java 1.7 uses - it locks any jar that it loads and doesn't release the jar until execution completes. The easiest solution is to use Java 1.7 which should solve this problem. Otherwise you can write your own custom ClassLoader (ugh). Default ClassLoader: http://docs.oracle.com/javase/6/docs/api/java/net/URLClassLoader.html
EDIT
And here's the note from Oracle saying they fixed it in Java 1.7: http://openjdk.java.net/projects/jdk7/features/#f584
I dont see a possibility of replacing the jar that you are executing from within the program. Suggested Approach. Create a new jar with a simple class that just launches your existing application. Before tha launch it should check if the temp.jar exists and if exists delete original and rename the temp.jar to original. In your application after creating the temp.jar, lauch the launcher class using Runtime.exec and exit. Your app will restart with new jar.
May be you would need to write a custom class loader(extending ClassLoader) which enables you to load/unload the jar. You should be able to delete the jar if you can unload the jar.
Useful links
http://docs.oracle.com/javase/tutorial/deployment/jar/jarclassloader.html
Can I dynamically unload and reload (other versions of the same) JAR?

How to refer a jar outside exe in Java desktop application?

I have a Java application installed. The jar is bundled into an .exe file using Launch4J. Now I want to create a patch for this application.
If I create another jar containing only updated files, how can I refer it in the original code?
I have java application installed. ..Now I want to create a patch for this application.
This is one of the strengths of the Java Web Start launch technology that comes with the J2SE. Simply update the Jar on the server, and the next time the app. launches, it will be updated.
The update can be honed for your use-case, configured to be done lazily or eagerly, before or after launch, or even programatically controlled using the JNLP API's DownloadService.
..And the jar is bundlled into an .exe file ..
'Unfortunately', JWS works on Windows, ..and Mac., and *nix - so you may have to expand your horizons.
BTW - I have no idea how to do the same with Launch4J, but then, that is really the wrong question. I aim to provide an answer to the right question, which is "How do I deploy & update a Java rich client?". ;)
I've never worked with Launch4J, however I think you should try to affect the classpath. JRE always loads the classes from the classpath. From this point of view, jars have no added value and just serve as a containers for your *.class files and resources.
Now, if you succeed to configure your tool to do something like:
classpath = C:\Temp\my_patch_path;$your_current_classpath
then its enough to put your changed files into C:\Temp\my_patch_path (of course preserving the package structure). JRE will load your classes first in this case.
Hope, this helps
Mark
It is might not be possible to do this without changing the contents of the exe.

Can you determine if Vista UAC allows writing to a directory without elevation in java?

Here is the scenario. I have an application which writes a configuration file in its directory (user.dir). When the user cannot write to that directory due to UAC issues, I would like to change that to write to user.home/.appname/. The problem is that Windows really lies to my application and writes to user.dir which is in the Program Files directory, but although it allows the write and the read (even after restarts) it doesn't store it there, it stores it in a hidden directory (the home directory/AppData/Local/VirtualStore/Program Files/appname), making it hard/impossible for the user to find if they want to edit the file.
However, I don't want to just change my application to write to user.home and be done with it because some users run the application off of a USB drive, at which point I want to use user.dir if it is available, because it would not be helpful to leave things around the user home directory in that scenario (on a guest computer).
So after that rather long winded background, is there a way from java to know if the local directory is really truly directly writable from Java or if vista is going to instead virtualize the directory writes to another location?
This problem occurs if the Java executable is not marked as Vista compatible (using the manifest). The current release from Sun is marked as compatible. So the simplest solution is to use the latest release. This means that now neither files nor registry entries are virtualised.
Edit from author of OP:
Java 6 Update 10 (bug 6722527) added the manifest to the relevant files. Bug 6737858 addressed further issues, and is recorded as fixed in Release 12, although it is not in the release notes. For JDK 1.5, the installer was fixed in Update 11, however there will be no manifests added to the exe by Sun. You can add one yourself by putting the manifest file in the same directory as the exe if it is important enough.
After writing your file, can you just check that the file suddenly appeared in virtualized directory? I'd do a small "touch" file at app start to set a global boolean variable userUserHome.
Prepare a native EXE that loads the JVM in process (java.exe does this but you will need your own).
Add a manifest file (or in RC data) that specifies UAC as invoker.
Try writing to the folder to see if it works.
Or decide this is too much work and use a config file.

Categories