Checking For Updates
This chapter explains the background behind update checking and introduces you to the API that allows you to integrate these checks into your application.
The updates.xml file
The updates.xml
file is created in the media output directory
each time you build the project. For advanced use cases, you can modify this file before uploading it to the
web server. The file looks like the sample below:
<?xml version="1.0" encoding="UTF-8"?> <updateDescriptor baseUrl=""> <entry targetMediaFileId="8" updatableVersionMin="" updatableVersionMax="" fileName="hello_windows_4_0.exe" newVersion="4.0" newMediaFileId="8" fileSize="2014720" bundledJre="" myCustomAttribute="showWarning"> <comment language="en">Hello world</comment> <comment language="de">Hallo Welt</comment> <comment language="it">Ciao mondo</comment> </entry> <entry targetMediaFileId="9" updatableVersionMin="" updatableVersionMax="" fileName="hello_linux_4_0.rpm" newVersion="4.0" newMediaFileId="9" fileSize="817758" bundledJre=""> <comment /> </entry> <entry targetMediaFileId="10" updatableVersionMin="" updatableVersionMax="" fileName="hello_macos_4_0.dmg" newVersion="4.0" newMediaFileId="10" fileSize="1359872" bundledJre=""> <comment /> </entry> </updateDescriptor>
Its contents are derived from your input on the "Installer->Auto-Update Options" step where you define global options and common options that are replicated on all media file entries.
On the "Customize project defaults->Auto-update options" step of the media wizard you can override settings with specific values for each media file.
The root of the updates.xml
file is the updateDescriptor
element. It has a
baseUrl
attribute that can be used to specify an alternate download URL for the installers and
contains the value of the "Base URL for installers" setting on the "Installer->Auto-Update Options" step.
By default, it is empty which means that the installers must be located in the same directory as the
updates.xml
file.
The updateDescriptor
element contains one or more entry
elements that correspond
to the media files that were created by the build.
When install4j determines whether an entry in the update descriptor is a match for the current installation,
it looks at three attributes of the entry
element: Most importantly, the
targetMediaFileId
attribute has to match the media file ID of the current installation.
You can show media file IDs by toggling the "Show IDs" toolbar button
Another criterion is the installed version of the application. Depending on that version, you might want to
offer different updates. The updatableVersionMin
and the updatableVersionMax
attributes can set lower and upper limits for the installed versions that should
download the associated entry in the update descriptor. By default, these attributes are empty, so no
version restrictions apply. On the "Installer->Auto-Update Options" step, these versions can be set
for all media files.
Attributes that describe the update installer include fileName
which is necessary to
construct the download URL, and fileSize
which contains the size of the file in bytes.
newVersion
contains the available version while newMediaFileId
is the media
file ID of the update installer which is usually the same as targetMediaFileId
. Lastly,
bundledJre
contains the original file name of the JRE bundle without the .tar.gz
extension or the empty string if no JRE is bundled in the installer.
If you discontinue a media file, you can migrate users of that media file to a different media file with the
legacy media file setting on the "Customize project defaults->Auto-update options" step of the media wizard.
For each specified legacy ID, the entry for the current media file is duplicated, but with the
targetMediaFileId
attribute set to the legacy ID.
For more complex scenarios, you can modify the updates.xml
file yourself and
add additional entry elements as required.
In addition to the above attributes, the nested comment
elements can contain a localized
description that should be displayed to the user. You can populate these elements for all media files by
configuring the "Files with comments" setting in the "Installer->Auto-Update Options" step. The main
use case for this feature is to display release notes in the update downloader.
Finally, you can add any number of arbitrary attributes to the entry
element.
This is configured with the "Additional attributes" setting in the "Installer->Auto-Update Options" step.
Additional attributes are useful for custom logic to select a suitable update installer in the update downloader.
The update descriptor API and up-to-date checks
The install4j runtime API contains the
com.install4j.api.update.UpdateChecker
utility class that can download the updates.xml
file and translate it to an instance of com.install4j.api.update.UpdateDescriptor
. From there, you
can get a suitable com.install4j.api.update.UpdateDescriptorEntry
with a single method call:
import com.install4j.api.launcher.Variables; import com.install4j.api.update.*; String updateUrl = Variables.getCompilerVariable("sys.updatesUrl"); UpdateDescriptor updateDescriptor = UpdateChecker.getUpdateDescriptor(updateUrl, ApplicationDisplayMode.GUI); if (updateDescriptor.getPossibleUpdateEntry() != null) { // TODO an update is available, execute update downloader }
See the Javadoc for more detailed information.
In this way, you can display your own notification that announces the new version and lets the user decide
whether to download it or not. This API is primarily intended for use in your application. The "hello" sample
project shows how to use it in a complex example, see the source file hello/gui/HelloGui.java
in your install4j installation and look for the checkForUpdateWithApi
method.
In a custom installer application, you would rather use a "Check for update" action that performs the same
actions as UpdateChecker
and saves the downloaded UpdateDescriptor
to an
installer variable. All update downloader templates included with install4j execute the "Check for update"
action at some point. Its URL is set to ${installer:updatesUrl?:${compiler:sys.updatesUrl}}
by default. If you start the update downloader with the argument -VupdatesUrl=<URL>
, it
will define the installer variable "updatesUrl" and that value will be used as the URL. Otherwise, it falls back to
the compiler variable "sys.updatesUrl" that contains the URL for updates.xml
that you have entered
on the "Installer->Auto-Update Options" step.
Instances of UpdateDescriptorEntry
expose all attributes of the corresponding
entry
element in the updates.xml
file. They also provide access to any additional
attributes that were added to the entry
element so you can implement custom logic to find a
suitable update. The most important method of the UpdateDescriptorEntry
class is the
getUrl()
method that constructs the full URL from which the update installer can be downloaded.
If no baseUrl
has been specified on the updateDescriptor
root element, the
URL starts with the parent directory from which the updates.xml
file has been downloaded.
Update schedule registry
A common requirement is to check for an update on a regular schedule. install4j comes with a standard implementation of an update schedule registry that frees you of the task to implement one yourself. This update schedule registry is fully integrated with the launcher integration that starts update downloaders when launchers are executed, but it is also available in the API.
The com.install4j.api.update.UpdateScheduleRegistry
class is intended to be used in your
application. You configure a particular UpdateSchedule
by calling
import com.install4j.api.update.*; UpdateScheduleRegistry.setUpdateSchedule(UpdateSchedule.DAILY);
and call
boolean shouldCheckForUpdate = UpdateScheduleRegistry.checkAndReset();
each time your application is started. If you get a positive response, you can start a suitable update downloader
with the ApplicationLauncher
class as explained below.
To facilitate the configuration of the update schedule in your installer, install4j offers a special "Update schedule selector" form component whose initial value is set to the current setting (if any) and automatically updates the setting for the installed application when the user clicks "Next".
Starting update downloaders from your own code
If you have a GUI application, you could provide integration with the update downloader by offering a
"Check for update" menu item or similar that invokes the update downloader. One problem in this scenario is that
if the updater downloads and executes the update installer, your application will still be running and the user
will receive a corresponding warning message in the installer. The solution to this problem is to use the
com.install4j.api.launcher.ApplicationLauncher
class to launch the update downloader. With this
utility class, you can launch the update installer by passing its ID as an argument. IDs of installer applications
can be shown by toggling the "Show IDs" toolbar button.
If you launch an installer application such as an update downloader that way, the "Shut down calling launcher"
action will be able to close your application. To react to the shutdown and perform cleanup operations,
you can pass a callback to the ApplicationLauncher.launchApplication(...)
call. After you
are notified via the callback, your application will be terminated with a call to System.exit()
.
For example, for an update downloader with ID 123:
import java.io.IOException; import com.install4j.api.launcher.ApplicationLauncher; try { ApplicationLauncher.launchApplication("123", null, false, new ApplicationLauncher.Callback() { public void exited(int exitValue) { //TODO update check complete, no update available } public void prepareShutdown() { //TODO update installer will be executed, perform cleanup before the process is terminated } } ); } catch (IOException e) { e.printStackTrace(); //TODO handle invocation failure }
To easily get such a code snippet for invoking the update downloader, select the update downloader application and click on the Start Integration Wizard button on the right.