It is as simple as an application that can update itself.
More specific, maybe a launcher that loads a jar file from the web and replaces it with the current jar.
The approach that I want is:
A launcher which is coded in Java.
That launcher overall uses classloader e.t.c.
I want to keep the data from the previous jar. Maybe the data from the previous jar are written on a .txt file and pass them to the new one? (If possible)
I have no clue about classloader or any direction to follow.
So my question is "How can i use classloader to create an auto-update Java application?".
P.S. I want java web start to be the last choice. Some lines of code would help me very much.
Edit: I understand completely what are you saying in theory. What i am looking for is specific links or code which i can take as reference.
The question isn't a duplicate because i can't find links or code but theory.
You can use the URLClassLoader to load a jar file from an URL. Mind, URLs may also be local files, and I'd recommend that you download the jar file locally before loading it in, instead of loading it directly from the web. The reason for this is that you want the application to remain usable, even if the user cannot reach your server.
However, I'd also recommend against taking this approach. What if you want to update the launcher? It's better to download a seperate updater application from the main application, launch the seperate updater application, have that kill the main application and update it.
Related
This question already has answers here:
How can I write a Java application that can update itself at runtime?
(9 answers)
Closed 4 years ago.
What a really need is a java application that checks for new updates from an XML or TXT file from the internet which shows the files that have been updated like the following:
V.1.0.5
class1.java
img/img1.jpg
V.1.0.6
class1.java
class3.java
class4.java
The App. Should check Updated from his Current version to the latest and make a list of the updated files, in this case is should be:
class1.java
img/img1.jpg
class3.java
class4.java
The app Should then download this files from a link like : http://webadress.com/appfiles/XXXXXXX where XXXXXXX is the file name.
The main problem i've faced is How Can the app download and replace this files within the Same app JAR file.
i've thinked about a bootstrap (SecondP App that launch the main app and check for updates . but can't really get it to work , As it should Extract the main app jar replace and download the new update files then re-archive the files in one jar file and launch it .
Simply what i really need is an application that can update it self on file by file bases not replacing the whole jar file. as bandwidth is really a huge matter.
Thanks a lot for help in advance :)
You need two separate programs in two separate JVMs: your program and the updater. The updater (possibly on user request) checks what should be downloaded, downloads the files and then warns the user.
The user than saves his work, shuts down the application and tells the updater to patch the application binaries, for example by replacing JARs, updating databases and/or configuration files, symbolic links and whatnot.
I don't know of any framework that can ease the writing of such a system - so likely you'll have to code every piece of code by yourself. Since it's not an easy task, you should consider the conservative alternative of simply writing a wizard (there are frameworks for this) that completely replaces the binaries and works for both first installation and upgrade. Also, consider that sometimes you'll need the updater to upgrade itself!
I’m coding my first java Desktop application using eclipse and I’m having difficulty deploying it. My project uses JavaFX2 and the e(fx)clipse plugin, the latter is in charge of generating the build.xml file.
ABOUT THE APP
The app, amongst other things, provides an interface where the user can create categories and associate these with labels. All modifications are saved within a single file (the data is stored as a serialized object.) and are supposed to be loaded automatically when the app is reopened.
THE PROBLEM
When build as an executable jar using a .xml file (Ant), the project runs fine within the folder where it gets created. I can run my application, modify data, and save everything once I’m done. When I reopen the app everything gets loaded as it should.
However, if I copy the folder elsewhere, I can no longer save any data. Everything else seems to work; the app will even load the data that was saved when it was in its original directory. I assume that this means that the app can still see the data file, but can no longer write to it.
WHAT IVE TRIED
I’ve read that warping the .jar around an installer may fix the issue; however, one of the goals for the app was to make it as portable as possible. Meaning that it should be possible to move it around from one directory/computer to another, ideally in a manner that is cross-platform friendly, without the need of installing it.
I’ve tried various things to get it to work. I’ve shifted the whole project to Netbeans (to produce a different build), I’ve modified the save/load method file path to make sure the right document is targeted, I’ve tweaked the .xml file the best I could, and I even tried to build the project using the javafxpackager. No matter what I do, when the build works, I get the same results.
Right now, I’m thinking that there may still be something wrong with the .xml file but I’ve got a hard time understanding how to modify it. Perhaps the problem is somehow caused by the way the data gets serialized. I know that at one point when I moved things around within my project, both the save and load methods could no longer interact with the data.
What I find strange is that when the project is moved the load method still works. If the problem is caused by changing the file path, how come only the save method ceases to function?
APP FILES AND STRUCTURE
+src
-(Main.java)
+controller
-(misc.javas)
+modelData
-(Library.java) -->the object that is serialized
+modelLogic
-(misc.javas)
+view
-(misc.javas)
+files
-(library.data) -->the file where the serialized object is saved
+lib
-(empty.empty)
So, is their anything I can do to solve my problem?
Thanks in advance.
In the end, the problem was rather simple. When I was moving the app, I was always putting it on the desktop, which, in the case of my PC, sets by default all content as read-only (in relation to the app's privileges). Because of this, the app could not modify any files that were within folders on the desktop.
Therefore, all I had to do was to move the app to another directory, such as C:\randomFolder, and the problem was solved.
So, if anyone has a similar problem, moving the app elsewhere may be the solution. Alternatively, taking full ownership of the folder and its content can also work.
When possible, it is usually better to have the app ask its user for a specific location to save its data.
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.
I'm looking for a non-webstart/jnlp solution.
I'd like to add to my app an update feature that checks in an ftp or http server and downloads the last version (if there is a newer one) replacing the libs that has been changed.
How can i do that? I want to implement something like JDownloaders updates.
Thanks
It looks like you just described exactly how to do it. Add an update feature that checks an FTP or HTTP server and downloads the latest version.
Remember that you cannot download and overwrite a file which is in use. So you have two options for a design from where I sit:
When you start up the application, copy all of the jar and library files to a /temp folder of some sort before running them. Then, when you download the update, overwrite the files in the original place. The next time the application starts up, it will use the new files.
When you start up the application, first startup an updater. Have it connect to the server and compare all of the file versions. It will be able to overwrite any of the application files because it doesn't use them. It only uses the updater jar. Once this is done and everything has been updated, then start a new process from the updater with the actual application. You will also need to put some code in to be able to update the updater jar. Either make the main application be able to update the updater, or use the first technique and run the updater from a copy of the updater jar.
Remember when you download the files that you should be downloading them to a temporary location and then moving them to the right place when they're done. This will make sure that you never leave your application in a "half-downloaded" state.
Beyond that, getting this to work is going to be about a lot of testing. Good luck!
Have a look at http://code.google.com/p/getdown/
According to this question on stackoverflow it seem to be a viable alternative for web start (at least worth having a look at).
I am currently working on desktop software based on java.It's quite a big code base (more than 40 jar files).
I wish to provide an automatic update functionality. The desktop software constantly checks one back end system to see if there are new versions of the jar files available.
The problem now is: How to replace the updated jar files?
If you deploy your application using Java Webstart (JNLP), you get this mechanism almost for free...
From http://mindprod.com/jgloss/javawebstart.html
The key benefit for Java Web Start is automatic update without having to download the entire program every time.
Easiest would be to check for updates on each startup, download the updates and then launch your application. I think this is the way that Java Web Start works (see aioobes answer).
More complex would be to use either the netbeans or eclipse framework for your application. Both are rather complex and you will have to rewrite your application to work with them. This solution supports live updates.
As far as I am aware there is no easy way to update a running application. It is possible to load new versions of a class with a different classloader, but not possible to unload old versions while they are still referenced.
You can make a little server and a launcher which downloads the newest version, replaces the old one, and starts the jar with:
Runtime.getRuntime().exec("java yourjar -jar");
And you terminate the launcher with:
System.exit(1)
You can also serialize down your state (keep it in memory) and then create a new ClassLoader instance pointing to the new .jar files. Then serialize up your state again using this new classloader. You have just changed the underlaying .jars within a executing product.
Please note that you do not need to change the classloader for everything only for the part that is actually using the .jar files. This can be tricky to conclude what parts that are. And you might get nasty linking errors if done wrongly. So..
.. to keep it simple, use WebStart or a preloader that updates the .jars and then starts the main app (basically what WebStart does for you).
A reason for rolling your own, is that you can use your own format for the .jars, encryption, other packing formats etc.
After reading some answers to many auto-update questions, I thought of a solution. This is how I would implement a secure auto-update for a Java/Kotlin jar application.
Assumption: the installer will contain two jars: a launcher and the main application. Any shortcuts created will point to the launcher, but still be the name of the application. The release will contain the main application and the installer.
The launcher is launched first:
First check if an update has already been downloaded as app_name_update.jar
if an update has been downloaded, rename app_name_update.jar to app_name.jar
Start app_name.jar
This part does not have to be in the launcher, but it's preferred as to not slow down the main application: at this point, the launcher should check for an update (e.g. GitHub releases API) and download it to {CWD}/unverified_app_name_update.jar.
Compare the hash of unverified_app_name_update.jar to an online location containing hashes for all published versions. hashes.txt would be an example found in the same github repository. If the software is open-source, GPG signed commits is a must and the launcher should check if the latest update is a verified commit! If its a proprietary application, keep the hashes.txt at a separate URL from the release where your company does not control the infrastructure (e.g. GitHub).
Main app launched:
No need to check for updates unless updates are mandatory, in which case check for update -> if update found, start loading animation "updating" while you can detect that the launcher is still running. Ensure that the launcher has no race condition while loops!
I found ready project to solve automatically updating.
You can update your app, in your cases you can update jars and resources of your desktop app. The idea of the this is next: wrap you app with starter which can control updating and running you app. In details you can find here.