I would like to implement a java application (server application) that can download a new version (.jar file) from a given url, and then update itself at runtime.
What is the best way to do this and is it possible?
I guess that the application can download a new .jar file and start it. But how should I do the handover, e.g. know when the new application is started and then exit. Or is there a better way to do this?
The basic structure of a solution is as follows:
There is a main loop responsible for repeatedly loading the latest version of the app (if required) and launching it.
The application does its thing, but periodically checks the download URL. If it detects a new version it exits back to the launcher.
There are a number of ways you could implement this. For example:
The launcher could be a wrapper script or binary application that starts a new JVM to run the application from a JAR file that gets replaced.
The launcher could be a Java application that creates a classloader for the new JAR, loads an entrypoint class and calls some method on it. If you do it this way, you have to watch for classloader storage leaks, but that's not difficult. (You just need to make sure that no objects with classes loaded from the JAR are reachable after you relaunch.)
The advantages of the external wrapper approach are:
you only need one JAR,
you can replace the entire Java app,
any secondary threads created by the app, etc will go away without special shutdown logic, and
you can also deal with recovery from application crashes, etc.
The second approach requires two JARs, but has the following advantages:
the solution is pure Java and portable,
the changeover will be quicker, and
you can more easily retain state across the restart (modulo leakage issues).
The "best" way depends on your specific requirements.
It should also be noted that:
There are security risks with auto-updating. In general, if the server that provides the updates is compromised, or if the mechanisms for providing the updates are susceptible to attack, then auto-updating can lead to a compromise of the client(s).
Pushing a update to a client that cause damage to the client could have legal risks, and risks to your business' reputation.
If you can find a way to avoid reinventing the wheel, that would be good. See the other answers for suggestions.
I am currently developing a JAVA Linux Daemon and also had the need to implement an auto-update mechanism. I wanted to limit my application to one jar file, and came up with a simple solution:
Pack the updater application in the update itself.
Application: When the application detects a newer version it does the following:
Download update (Zipfile)
Extract Application and ApplicationUpdater (all in the zipfile)
Run updater
ApplicationUpdater: When the updater runs it does the following:
Stop the Application (in my case a daemon via init.d)
Copy the downloaded jar file to overwrite current Application
Start the Application
Cleanup.
Hope it helps someone.
I've recently created update4j which is fully compatible with Java 9's module system.
It will seamlessly start the new version without a restart.
This is a known problem and I recommend against reinventing a wheel - don't write your own hack, just use what other people have already done.
Two situations you need to consider:
App needs to be self-updatable and keep running even during update (server app, embedded apps). Go with OSGi: Bundles or Equinox p2.
App is a desktop app and has an installer. There are many installers with update option. Check installers list.
I've written a Java application that can load plugins at runtime and start using them immediately, inspired by a similar mechanism in jEdit. jEdit is open source so you have the option of looking to see how it works.
The solution uses a custom ClassLoader to load files from the jar. Once they're loaded you can invoke some method from the new jar that will act as its main method. Then the tricky part is making sure you get rid of all references to the old code so that it can be garbage collected. I'm not quite an expert on that part, I've made it work but it wasn't easy.
First way: use tomcat and it's deploy facilities.
Second way: to split application on two parts (functional and update) and let update part replace function part.
Third way: In your server appliction just download new version, then old version releases bound port, then old version runs new version (starts process), then old version sends a request on application port to the new version to delete old version, old version terminates and new version deletes old version. Like this:
This isn't necessarily the best way, but it might work for you.
You can write a bootstrap application (ala the World of Warcraft launcher, if you've played WoW). That bootstrap is responsible for checking for updates.
If an update is available, it will offer it to the user, handle the download, installation, etc.
If the application is up to date, it will allow the user to launch the application
Optionally, you can allow the user to launch the application, even if it isn't up to date
This way you don't have to worry about forcing an exit of your application.
If your application is web based, and if it is important that they have an up to date client, then you can also do version checks while the application runs. You can do them at intervals, while performing normal communication with the server (some or all calls), or both.
For a product I recently worked on, we did version checks upon launch (without a boot strapper app, but before the main window appeared), and during calls to the server. When the client was out of date, we relied on the user to quit manually, but forbid any action against the server.
Please note that I don't know if Java can invoke UI code before you bring up your main window. We were using C#/WPF.
If you build your application using Equinox plugins, you can use the P2 Provisioning System to get a ready-made solution to this problem. This will require the server to restart itself after an update.
I see a security problem when downloading a new jar (etc.), e.g., a man in the middle attack. You always have to sign your downloadable update.
On JAX2015, Adam Bien told about using JGit for updating the binaries.
Sadly I could not find any tutorials.
Source in German.
Adam Bien created the updater see here
I forked it here with some javaFX frontend. I am also working on an automatic signing.
I would like to write a program that sends an automated email based on a timer that runs constantly. I would then like to somehow export this program from eclipse to a computer that does not run the ide, and run it constantly in the background. I have figured out the code to send emails through java, my question is more regarding how to export this project as an application (or something) that can be run on any computer without running it through the eclipse IDE.
Any help, or directions to a better a resource to learn from, would be greatly appreciated.
The simple (manual) approach to turning a Java program into something that runs outside Eclipse:
Create a runnable JAR following the instructions here: http://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Ftasks%2Ftasks-37.htm.
If your application depends on library methods that are not part of the Java SE library, pay particular attention to the "select library handling strategy" step.
Run the application from the command line as follows:
$ java -jar yourapp.jar arguments ....
Obviously, you need at least a Java JRE installation on the execution platform to run java, and you should have configured your system (the $PATH or %PATH% environment variable) so that typing java runs the correct thing.
If you are using a build system like Maven, Ant, Gradle and so on, you can automate the step that generates the JAR. (In fact, you can automate the entire build ... and break your dependency on any IDE.)
I DO NOT recommend trying to create an "executable" for your Java application. For a start, executables cannot be run on any computer. They can only be run on computers running a specific operating system / OS family. A second problem is that you are effectively embedding a JRE in your application. That makes applying the latest Java security patches difficult.
As for the problems of keeping the application running "constantly" and sending emails at specific times, that is just Java programming.
Use Timer & TimerTask - e.g. http://www.mkyong.com/java/how-to-run-a-task-periodically-in-java/
Use a job scheduler. For instance Quartz has an easy to use API for running jobs on a fixed schedule: http://quartz-scheduler.org/documentation/quartz-2.x/tutorials/tutorial-lesson-06
You need to create a runnable executable. You can do this by following these steps: http://www.wikihow.com/Create-an-Executable-File-from-Eclipse
Regarding the timer/scheduler, you may consider using Windows Task Scheduler (on Windows platform) or cron (*nix platform).
You will probably need to provide more information about the requirements you have for the timer in order to get a more specific answer there.
So I have just packaged my JavaFX 8 application using the zenjava maven plugin in eclipse. Unfortunately my application performance outside of Eclipse is abysmal. The application connects to an online database that I have set up and allows users to query items in the database. When I run the application in Eclipse it takes 3-6 seconds to start up, but when I am running commands in it the response is almost instant. Now that I have my jar packaged and running on my terminal it takes at least 10 seconds to start up and responses are frustratingly slow.
I have seen that the option -Djavafx.autoproxy.disable=true has helped many people overcome what seems a similar problem, but when I run
java -jar -Djavafx.autoproxy.disable=true application.jar arg
it is not any faster than it was originally. Most of the other ways I have seen to deal with this is done in Netbeans, which I do not use. Curious if anyone has dealt with this in Eclipse and can provide any insight? Thanks!
I have a jar file which contains two Java classes. Using the javamail API I have developed these classes to read and edit my mail, then send to another mail id.
I am able to execute this through my standalone system via Eclipse. Now I want to host this jar file somewhere remotely so that it would fetch the data in real time and execute the job regularly. I have contacted couple of hosting sites and they are saying that they require a war file instead.
Does anyone have any suggestions to this problem?
To give you another point of view and to be constructive, I would go with embedding your jar into a war application and you get some things for free, the most important I think is that you gain a managed application lifecycle so with a standard web application context listener you can start and stop your program in a managed way. Besides you have more hosting options and it is less work.
Good luck with that.
As I don't know of any services specifically for plain execution of executables, your best bet is probably getting a cheap VPS. With some searching you can probably find one that would work for around $5 USD/month. For a single simple app you'd only need around 128MB of memory.
Pick one up, install Java (whatever Linux distro you get probably has OpenJDK in the repositories), copy your files over, and set up a cron job to run the executable at a set interval.
For easier administration, install something like webmin and use that to configure the cron job. The command would likely just be java -jar /path/to/my/App.jar, and you can use the web interface to configure the intervals for the command to be executed.
For an app like this, I would avoid anything related to a war file. You aren't making an application with a web interface (like a PHP app or some such) so it really wouldn't be appropriate. You would have to write some extra code to make it compatible with a container like Tomcat, and on top of that the memory requirements for running the application server would be a lot higher.
I am writing an application for taking backup of user data. In my application i have to perform incremental backup operation. for performing incremental backup i am trying to use rsync algorithm.
i am writing application for windows version. I am having linux hosting server for storing files. after some search i got two lib "jarsync-0.1" and "sisyphe-0.92" but "jarsync-0.1" is
a beta release jar and not giving appropriate result. and "sisyphe-0.92" is configued with linux o.s.
Please could you suggest me any lib file in java that can be used for rsync (for windows version).
There is currently no complete Java port of rsync.
In your case I would look into a native rsync you could call. DeltaCopy has an rsync GUI for Windows which may be useful.. http://www.aboutmyip.com/AboutMyXApp/DeltaCopy.jsp
I guess, this is going to remain unanswered. Since there are no rsync libraries for Java being actively developed.
I just found there is already a discussion on this topic here.
Apparently, most of the guys happen to have implemented rsync via system calls(i.e invoke native calls via your Java app).
The only way I see this application can be coded is via native rsync calls to the OS. Since there are no actively developed java implementations available for rsync. So my suggestion would be to download rsync utility which works in command line and call the utility via process calls in your code.
This is the best possible solution I could think of as of now.