Introduction

jDeploy allows Java developers to deploy desktop applications as native bundles on Macintosh, Windows, and Linux. Unlike other deployment solutions, jDeploy doesn’t require any third party tools (other than OpenJDK), and can build native installers for Mac, Windows, and Linux on any platform. For example, you can build a native Windows installer on Linux or Mac, and vice versa. Applications deployed using jDeploy can also receive updates automatically as they become available, so that can be assured that your users will always be working with the latest version of your application.

Note
Apps distributed with jDeploy can also be installed as command-line apps using npm. See Command-line Distribution for more information about that.

GUI

jDeploy provides a graphical user interface that makes it easy to configure your app’s deployment settings such as icons, splash screens, file associations, etc…​ After you’re satisfied with the settings, press "Publish", and it will publish your app so that users can download the latest version.

details tab
Figure 1. The jDeploy GUI allows you to configure and publish your app.

Download Page

When you publish your application using jDeploy, your users will instantly be able to download your app at https://www.jdeploy.com/~YOUR-APP-NAME

swingset download page
Figure 2. Example download page the Java SwingSet demo app.

The download page includes links for Windows, Mac, and Linux. At time of writing, Linux includes two different download types: .deb, and .bin, but more may be added as there is demand.

The Installer

The installer that is downloaded from the download page will prompt the user to select relevant installation options, such as whether to add a link in the Dock (Mac only), or the Start Menu (Windows Only), and whether to enable auto-update (default "On").

swingset installer mac
Figure 3. SwingSet2 Installer on Mac

After selecting the desired options, the user can press the Install button, which will trigger the installation of your app. This will only take a second, and, when complete, the user will be prompted with a dialog as follows:

swingset success mac
Figure 4. Dialog shown after successful installation.

In this example, clicking on the "Open SwingSet2", will open the app as shown below:

swingset mac
Figure 5. The SwingSet2 Demo application, running on Mac OS

Mac Codesigning and Notarization

When you deploy your app with jDeploy, you don’t need to sign or notarize it as you normally would when deploying a Mac application. jDeploy handles all of this so you don’t need to worry about it. You don’t require any apple certificates; nor do you require an Apple developer accounts. Mac users running the latest versions of Mac OS (tested on Mojave through Monterey) will be able to download and install your app, by simply downloading it from the jDeploy download page, and running the installer.

Java Versions

jDeploy currently uses Azul’s OpenJDK REST API to download an appropriate JRE, or JDK on demand. You can specify which version of Java your app requires in your jDeploy config file. You can also specify whether your app requires a full JDK, or JavaFX. Deploying JavaFX apps with jDeploy is actually quite painless - as you don’t need to bundle the JavaFX jars or modules with your distribution.

At time of writing, LTS (long-term-support) Java versions from 8 through 17 are supported.

Publishing to NPM

jDeploy uses npm for cloud publishing of your app. When you publish a new version to npm, your app will automatically detect this the next time it is launched, so that you can be sure that your users are always working with your latest version.

Important
Publishing the app to NPM requires an NPM account. This takes a few seconds to set up. You can simply type npm adduser and follow the prompts. full instructions on the NPM site. If you already have an account but haven’t logged in on the current machine you would use npm login to login and store the credentials locally.

Getting Started

Requirements

JDK

In order to run jDeploy, you need to have JDK 8 or higher installed on your development machine. Several free distributions are available including Adoptium (formerly AdoptOpenJDK), Zulu, and Corretto.

NodeJS

jDeploy uses npm for its distribution because it simplifies the installation process dramatically. npm comes packaged with NodeJS, which can be downloaded here.

Tip
We recommend using the latest version of NodeJS that is available, as that will ensure compatibility. At time of writing, we are using NodeJS 14.15.4 and npm 8.3.0 (which is bundled with NodeJS 14.15.4) for our testing.
npm Account

If you want to be able to publish your apps for others to use, you will also need an npm account. npm accounts are free, and it only takes a minute to create one. The signup page is here.

Installation

You can either install jdeploy globally, or locally. When you install it locally, it will only be available to the project that you install it into, and you would run it with npx jdeploy …​. When you install it globally, it will be available in your command-line path no matter where you are.

Installing Globally

npm install -g jdeploy
Important
On Mac and Linux you’ll need to use sudo to install globally. E.g. sudo npm install -g jdeploy

Installing Locally

cd /path/to/your/project
npm install jdeploy
Important
When you install it locally, it will create a directory named "node_modules" in the current directory, and jdeploy will be installed there. To run jdeploy, you would need to be in the project directory, and you need to use npx to run it. E.g. npx jdeploy …​.

Usage

Open a command prompt and navigate to your Java project directory.

cd path/to/myproject

Run the jdeploy command. E.g.

jdeploy

If this is your first time using jdeploy on this package, you’ll be prompted to create a package.json file:

create package json prompt

Press Yes.

This will open the jDeploy GUI, and it will look something like the following screenshot.

details tab

jDeploy will have already tried to generate some sensible settings here, but you should go over them yourself to make sure they are correct.

Tip
See the GUI help page for a thorough overview of the user interface.

The most important fields here are:

Name

The unique name of your app. This is used for publishing in the npm registry and must be unique in npm. You may want to search on npmjs.com to make sure that your name hasn’t been taken yet.

Version

The version of your app. This is used for publishing to npm. Each time you publish, you should increment the version number.

Title

The user-friendly title for your app. This is used in your app name, installer name, and download page.

Jar File

The main jar file for your app. This must be an executable jar file. See Appendix: Building Executable Jar File.

Icon

The icon for your app. This should be a 512x512 PNG with transparency.

Publishing Your App

Once you have configured your app to your liking, press the Publish button.

You might be prompted to log into npm if you haven’t already.

You will be shown a progress dialog with a readout of npm’s progress.

publish in progress

If it is successful, you’ll see a "Success Message" like the following:

publish success

As soon as you see this message, your app is live and available to download on your download page.

Command-line Usage

If you eschew GUIs and prefer to work on the command-line, the following instructions are for you.

In terminal, navigate to a directory containing an executable .jar file that you would like to publish.

$ jdeploy init

This will generate a package.json file with settings to allow you to publish the app to npm.

The package.json file

After this command completes, you should open the package.json in your text editor to adjust the settings to your requirements. The following is the package.json file for the SwingSet2 app.

{
  "bin": {"swingset2": "jdeploy-bundle/jdeploy.js"},
  "author": "Oracle",
  "description": "The Swing Sampler demo, packaged by jDeploy",
  "main": "index.js",
  "preferGlobal": true,
  "repository": "https://github.com/shannah/swingset2",
  "version": "1.0.5",
  "jdeploy": {
    "jar": "target/swingset2-1.0-SNAPSHOT.jar",
    "javaVersion" : "11",
    "title" : "SwingSet2",
    "javafx" : false,
    "jdk" : false
  },
  "dependencies": {"shelljs": "^0.8.4", "njre": "^0.2.0"},
  "license": "GPLv2+Classpath Exception",
  "name": "jdeploy-demo-swingset2",
  "files": ["jdeploy-bundle"],
  "scripts": {"test": "echo \"Error: no test specified\" && exit 1"}
}

The package.json specification can be found here. The jdeploy object includes additional properties that you can use to customize how your native desktop bundle. It includes the following keys:

jar

The path (relative to the package.json file) to your executable jar file. It the jdeploy init command worked correctly, it should already point to the correct jar file. If it found the wrong file, or the name of the file changes later, you may need to adjust this value.

Type: String

javaVersion

The Java runtime version required to run your app. At time of writing the default is "11". You can also use "8", or "17" here. In theory any version that Azul's API supports can be used here.

Important
This value should not include only the major version. E.g. "11", NOT "11.0". Also, this value should be a string, not an int. I.e. "javaVersion" : "11", NOT "javaVersion" : 11.

Type: String

title

Your app’s title. This is the human-readable name of your app. It will be used on the download page, and also as the app’s file name when downloaded.

Type: String

jdk

Whether the app requires a full JDK to run. If true, then the app will be run with a JDK - not just the JRE. Unless your app actually needs a JDK (i.e. access to javac, etc…​), you should keep this false as the JDK is substantially larger than the JRE.

Type: boolean

javafx

Whether your app requires JavaFX. If true, then the app will run with a JRE/JDK that includes JavaFX.

Type: boolean

Icons and Splash Images

There are three specially-named images that, if placed in the same directory as your package.json, will be used by jDeploy. They are:

icon.png

An icon for your app. If you don’t include this file, it will use a generic jDeploy icon for your app.

Recommended specifications: 512x512 pixels, with transparency.

Note
If you are using JavaFX you should also add your icon to your app’s Stage using stage.getIcons().add(…​) as there is a bug in Ubuntu that will cause the app’s icon to appear blank in the taskbar otherwise.
splash.png/splash.jpg/splash.gif

A splash image to be displayed while your app is loading.

Note
jDeploy uses the -splash:splash.gif CLI argument at runtime to add the splash screen. This apparently causes some issues with JavaFX. Currently, the recommendation for adding splash screens to JavaFX apps is to use a Preloader. Example here.
installsplash.png

A splash/info screen to be displayed in the installer for your app.

Publish App to NPM

Important
In order to publish your app with jDeploy, you need to have an npm account. For instructions on creating your free npm account see this tutorial.

You must be logged into your npm account in the command-line in order for the jdeploy publish command to work. If you already have an npm account you can login with the npm login command. See this tutorial for more details.

Once you have logged into your npm account and configured your package.json file to your liking, you can publish your app to npm with the following command:

$ jdeploy publish

If it completes successfully, you’ll be able to download your app bundles at https://www.jdeploy.com/~YOUR-APP-NAME where YOUR-APP-NAME is the name specified in the name property of your package.json file.

Publishing New Versions

If you make changes to your app, and want to publish a new version, you can increment the version property of your package.json file, and run jdeploy publish again.

File Associations

jDeploy allows you to associate your application with file mimetypes and extensions. For example, you can associate your application with .txt files so that it is listed as one of the options when users right click on a .txt file and select "Open with". Additionally, your application will respond when text files are dropped onto your app icon.

You can add file associations in the "Filetypes" tab of the GUI. Alternatively see File Associations In package.json for a description of how to add the associations directly in the package.json file.

filetypes tab

To add a new document type, press the add button button. To remove a document type, press the delete icon button in the corresponding row.

Each file type row includes the following fields:

Extension

The file extension. E.g. txt, html, mp4. Do not include the "dot".

Mimetype

The corresponding mimetype of the extension. You should provide both the extension and mimetype in each row, as some operating systems rely more heavily on one than the other.

Editor

Check this box if your app can edit files of this type. Leave it unchecked if it can only view files of this type.

Custom

Check this box if this is a custom mimetype. This is used on Linux as an indicator that the installer needs to register the mimetype in the system’s mimetype database.

File Associations In package.json

Such file associations can registered by adding the documentTypes property to the jdeploy object. E.g.

...
"jdeploy" : {

    ...
    "documentTypes" : [
      {
        "extension" : "txt",
        "mimetype" : "text/plain",
        "editor" : true
      }, {
        "extension" : "html",
        "mimetype" : "text/html"
      }, {
        "extension" : "jdtext",
        "mimetype" : "application/x-jdeploy-demo-texteditor-jdtext"
      }, ....
    ],
}
...

The documentTypes array may contain zero of more object entries, with the following properties:

extension

The extension of the file type. E.g. txt, html, etc…​

mimetype

The mimetype of the file type. E.g. text/plain, text/html, etc…​

editor

Boolean indicating whether the application can edit the file type. If omitted or false, the application will be regarded as a "viewer" for this file type.

custom

Boolean indicating whether this is a custom file type for your app. This is currently only used for .deb installers so that it knows whether it needs to register the mimetype with the system. Default is false

Accessing Files In Java

When a user launches your app by opening an associated file type (e.g. by dragging the file on your app icon, or selecting your app in the "Open with" menu), you will likely want to know which file triggered the launch. On Windows and Linux, these file paths are passed as arguments in your main() method. E.g.

On Linux and Windows opened files can be accessed in your main args.
public static void main(String[] args) {

    if (args.length > 0) {
        System.out.println("Received "+args.length+" file arguments");
        for (int i=0; i<arg.length; i++) {

            System.out.println("File: "+args[i]);
        }
    }
}

On Macintosh, you need to use the java.awt.Desktop class to be notified when the user opens a file with your app.

Using the FileHandler interface with the Desktop class to be notified when users open files with your app on Mac OS.
import java.awt.*;
import java.awt.desktop.OpenFilesHandler;
import java.awt.desktop.OpenFilesEvent;

public class HelloApplication {
    static {
        try {
            Desktop.getDesktop().setOpenFileHandler(new FileHandler());
        } catch (Exception ex){}
    }

    ...

    public static class FileHandler implements OpenFilesHandler {

        @Override
        public void openFiles(OpenFilesEvent e) {
            System.out.println("Received open files event "+e.toString());
        }
    }

    ...
}

URL Schemes

jDeploy allows you to register your application to open URLs with specific schemes so that, when a user clicks on a link with that URL scheme, your application will be launched.

You can add URL schemes in the URLs tab of the GUI. To add url schemes directly in the package.json file, see URL Schemes in package.json.

For example, you if you specify the "myapp" URL scheme, then you could add a link on your website as follows:

<a href="myapp:some-data">Open My App</a>

When users who have your app installed click on this link, they will be prompted to launch your app. When you app launches, you’ll be able to detect the specific URL that was clicked, so that you can respond appropriately.

The URLs tab is shown here:

urls tab

In the above example, the app would be associated with URLs like "jdtext:xxxxxx".

Adding Multiple URL Schemes

To add multiple URL schemes, you can simply add multiple values separated by commas in the text field.

e.g.

"myapp,podcast,feed"

In this case the app would respond to URLs like "myapp:…​", "podcast:…​", and "feed:…​"

Standard URL Schemes

You can associate your app with both custom schemes, and standard schemes. For a list of standard URL schemes that you might want your app to be ableto handle, see this wikipedia entry.

URL Schemes in package.json

Do this by adding a urlSchemes property of the jdeploy object with an array of string schemes.

E.g.:

"jdeploy" : {

  ...
  "urlSchemes" :  ["jdtext"]
  ...
}

With the above configuration in the package.json file, your app would be launched when the user clicks links like "jdtext:…​." in a webpage.

E.g.

Example HTML with link that will open in your app, assuming you have registered the "jdtext" URL scheme.
...
<p>Testing the custom jdtext url scheme.  <a href="jdtext:hello">CLick here</a></p>
...

Accessing URLs In Java

When a user launches your app by clicking on a link, you will likely want to know the URL that triggered the launch. On Windows and Linux, these URLs paths are passed as arguments in your main() method. E.g.

On Linux and Windows opened files can be accessed in your main args.
public static void main(String[] args) {

    if (args.length > 0) {
        System.out.println("Received "+args.length+" URL arguments");
        for (int i=0; i<arg.length; i++) {

            System.out.println("URL: "+args[i]);
        }
    }
}

On Macintosh, you need to use the java.awt.Desktop class to be notified when the user opens a URL with your app.

Using the URIHandler interface with the Desktop class to be notified when users open URLs with your app on Mac OS.
import java.awt.Desktop;
import java.awt.desktop.OpenURIEvent;
import java.awt.desktop.OpenURIHandler;

public class HelloApplication {
    static {
        try {
            Desktop.getDesktop().setOpenURIHandler(new URIHandler());
        } catch (Exception ex){}
    }

    ...

    public static class URIHandler implements OpenURIHandler {

        @Override
        public void openURI(OpenURIEvent e) {
            System.out.println("Received open uri event "+e.toString());
        }
    }

    ...
}

Homepage Verification

When users install your app, they will be prompted with a warning dialog to remind them to only install software from trusted sources. They are encouraged to review the app’s homepage to ensure that they trust the developer before proceeding with the installation. The dialog will look something like:

trust prompt dialog

By default it will report the software’s verified homepage to be the npmjs.org package page for your app. If you want this to report your actual website or GitHub repository, you’ll need to enter your your website URL into the "Homepage" field the "Details" tab, and then verify ownership.

homepage field

To verify ownership of this page, you’ll need to copy and past your app’s SHA256 hash code into your website. You can begin this process by pressing the "Verify" button beside the Homepage text field. It will display a dialog like the following:

verify homepage dialog

Click on the SHA256 hash code in this dialog to have it copied to the clipboard. Then paste it somewhere in your webpage. This can be hidden inside a meta tag, or just placed into the text of the page. As long as the jDeploy installer can make an HTTP request to your homepage and find the code amongst the page content.

Important
The sha256 hash code is generated based on the package name and the homepage URL, so if you change the homepage URL, the hash will change, and you’ll have to re-verify.

Once you have added the code to your homepage, press the "Verify" button so that jDeploy can check it. If everything looks good, you’ll see a success dialog like the following:

homepage verified
Important
This verification step is just a sanity check to ensure that you’ve pasted the code correctly. It doesn’t store this verification anywhere, and the jDeploy installer will perform its own check at install time whenever a user installs your app. This means that you shouldn’t remove the code after verification. You should leave it there permanently - or at least as long as you want your installers to be able to verify to your homepage.

Command-line Distribution

Apps distributed using jDeploy can also be installed in the command-line using npm. When distributing in this way, you’ll want to pay attention to the bin and name properties of your package.json file.

name

This is the name of our project as it will be listed in the NPM registry. This name must be unique. If you try to publish a project with a name that is already registered by someone else, it will fail. This name will be used by users who want to install your app. E.g. If "name"= "hello-world", then people would install my app by typing "npm install hello-world -g" at the command prompt.

bin

This specifies the name of the command that will be installed to activate your app. It actually maps an alias to the "jdeploy-bundle/jdeploy.js" script, which is thin bootstrap shell script for your java app. The entry will look like "bin" : {"hello-world" : "jdeploy-bundle/jdeploy.js"}. If you want to change your app’s command name to "my-hello-world", then you would just change "hello-world" to "my-hello-world".

You don’t need to do anything special to allow your app to be installed via the command-line. If you have published it using the jdeploy publish command, then, assuming your package name is "hello-world", users will be able to install your app by typing:

$ npm install hello-world -g

Some things to note:

  1. On Mac and Linux you’ll need to use sudo as it adds a symlink to /usr/local/bin which requires sudo permissions. On Windows it will work without sudo as long as you are using an Administrator account.

  2. If you omit the -g it will install the app locally (i.e. for use inside the current working directory). When installed in this way, you need to use the npx command to run your app, and it will only work when run inside the install directory.

They can then launch your app with:

$ hello-world

or, if they installed it locally, they would instead run it with:

$ npx hello-world

See Getting Started with jDeploy for Command-line apps for step-by-step instructions in deploying your command-line app.

Runtime Arguments

jDeploy allows you to configure JVM options, system properties, and program arguments for your application in the Runtime Args tab of the GUI, or the args property of the jdeploy object in the package.json file.

When working in the GUI, you should enter the arguments one per line in the provided text area. jDeploy supports a small set of placeholder variables that you can include in your arguments, that will be replaced at runtime. It also supports a minimal syntax for making platform-specific arguments, which are used on some platforms and not others.

runtimeargs tab
Figure 6. A sample Runtime Args tab demonstrating how to set a few JVM options, properties, and program arguments.

The above arguments would be saved in the package.json file as follows:

{
    ...
    "jdeploy": {
        ...
        "args": [
            "-Dmyapp.foo=bar",
            "-Xmx2G",
            "-D[mac]application.support.dir={{ user.home }}/Library/Application Support",
            "-D[mac]resources.dir={{ app.path }}/Contents/Resources",
            "gui"
        ],
        ...

JVM Options

JVM options are options that configure how the JVM works. They are always marked with the "-X" prefix. Some examples of commonly-used JVM options include:

-XmsXXX

Sets the minimum and initial size of the heap. E.g. -Xms2G. See the Java documentation for more information.

-XmxXXX

Sets the maximum sizeof the heap. E.g. -Xmx4g. See the Java documentation for more information.

System Properties

You can set system properties using the -D prefix. E.g. -Dmyapp.setting=foobar

Program Arguments

Arguments that are not prefixed with -X or -D are treated as program arguments. They will be passed to your program, and you can receive them in your main(String[] args) method.

Placeholder Variables

jDeploy supports a handful of placeholder variables that can be embedded in your run arguments, and will be replaced with the appropriate value at runtime. Placeholder variables are marked with {{ varname }}. The available variables are as follows:

{{ user.home }}

The path to the user’s home directory.

{{ exe.path }}

The path to the executable.

{{ app.path }}

The path to the .app bundle (when run on Mac). Otherwise it will be the same as {{ exe.path }}.

Platform-Specific Arguments

In some cases you may want a setting to only be applied on a specific platform. For example some JVM options may be mac specific. jDeploy provides a minimal syntax for marking an argument as platform-specific. For system properties, you would add a condition after the -D prefix, so instead of -Dfoo=bar, you would have -D[CONDITION]foo=bar where CONDITION is one or more platform names ("mac", "linux", "win") delimited by pipes. Some examples:

-D[mac]foo=bar

Same as -Dfoo=bar, but only on Mac.

-D[win]foo=bar

Same as -Dfoo=bar, but only on Windows.

-D[win|linux]foo=bar

Same as -Dfoo=bar, but only on Windows and Linux.

A similar syntax is used for platform-specific JVM options: -X[CONDITION]value, where CONDITION is one or more platform names ("mac", "linux", "win") delimited by pipes. Some examples:

-X[mac]ms2G

Same as -Xms2G, but only on Mac.

-X[mac|linux]mx4G

Same as -Xmx4G, but only on Mac and Linux.

Finally, for program arguments (i.e. arguments that are passed to your main(args) method), you can mark them as platform-specific by adding a -[CONDITION] prefix. E.g. -[mac]anArgOnlyAddedOnMac. Some more examples:

-[mac]foo

Same as foo, but only on Mac.

-[linux|win]foo

Same as foo, but only on Linux and Windows.

Building Bundles Locally

Important
When building your bundles locally, you still need to ensure that you run jdeploy publish to publish your app on npm, as the launcher relies on your published package for the automatic updates feature.

The easiest way to distribute your app is to just share the link to its download page at https://www.jdeploy.com/~your-app-name, however, you can optionally just generate your bundles locally as part of the jdeploy package step (which is included when you run jdeploy publish).

There are two flavors of packages that you can create:

bundles

The .exe, .app, etc.. bundles that launch your app directly.

installers

The installers that you can distribute to your users which install your .exe/.app, etc…​ bundles.

If you want to distribute your app to users, the installers provide a better experience since they include options to, for example, add your app to the programs menu (Windows/Linux) or the Dock (Mac).

You can generate bundles via the bundles property of the jdeploy object in your package.json file. E.g.

{
  ...
  "jdeploy" : {
    ...
    "bundles": ["mac", "win", "linux"],
  }

}

With this setting the jdeploy package command (and jdeploy publish) will generate your app bundles in the jdeploy/bundles directory. If you only wanted to generate a "mac" bundle, you would do:

"bundles" : ["mac"]

To generate installers, you can add the "installers" property. E.g.

"installers" : ["mac", "win", "linux"]

This would result in installer bundles being generated in the jdeploy/installers directory.

Note
The installers generated in this way may differ slightly from the installers available on your download page. This is because the download page uses a different mechanism for generating the packages. Additionally, the download page may provide some installer types that aren’t available locally.

Appendix: package.json Reference

jDeploy uses the package.json file to store all of its configuration details for a project. When you run jdeploy init it will create a default package.json file in the current working directory with default settings.

Note
For full documentation on the package.json file and its standard properties, see the npm package.json documentation.

Most of the jDeploy-related settings are located inside the "jdeploy" object. E.g.

{
    ...
    "jdeploy" : {
        "jar" : "dist/my-app.jar"
        ...
    }
}

However, there are a few properties at the "root" level that will affect how jDeploy deploys your application.

Main Root-Level Properties

The following standard properties are important to jDeploy.

Property Description Required Default

name

The name used to install your app from NPM. This must be unique in the NPM registry. E.g. If your "name" is

Yes

bin

An map containing the binaries for your application. This must contain at least one entry whose key is the name of your app as it will be called on the command-line, and value is "jdeploy-bundle/jdeploy.js"

Yes

dependencies

Must include a dependency on the "shelljs" library. "dependencies": {"shelljs": "^0.8.4"}

Yes

For other root-level properties see npm package.json documentation

Basic jDeploy Object Properties

The following properties should be placed inside the "jdeploy" object of the package.json, and are almost always used.

Property Description Type Required Default

javaVersion

The Major java version to use for your app’s runtime. Accepted values: "8", "11", "17".

String

No

"11"

jdk

Whether the app requires the full JDK to run. true or false

boolean

No

false

javafx

Whether the app requires JavaFX to run. true or false

boolean

No

false

jar

Relative path to the executable jar file that contains your app. You should supply either "war" or "jar", but not both. This value may be the path to a file, or a glob pattern (e.g. using * and ?) that can be used to match a file.

String

No

title

The human-readable title of your app. This is used in the download page, and in the app and installer names.

String

No

A modified version of the package name.

war

Relative path to a war file, or web-app directory that contains your web app. You should supply either "war" or "jar", but not both. This value may be the path to a file, or a glob pattern (e.g. using * and ?) that can be used to match a file.

String

No

Advanced jDeploy Object Properties

The following properties may be placed in the "jdeploy" object of the package.json file.

Property Description Type Required Default

args

List of runtime arguments. See Runtime Arguments.

Array<String>

No

None

bundles

List of the platforms to build bundles for when you run jdeploy package. E.g. ["mac", "win", "linux"]. Bundles will be built in the jdeploy/bundles directory. Not related to the bundles available on the download page. See Building Bundles Locally.

Array

No

None

files

List of copy rules for copying files into the the deployed application bundle. By default, for executable jar deployments, it will copy the jar file and all files listed in the jar’s class path (from its manifest file); and for war deployments, it will just copy what is inside the war file. If you need additional files to be deployed (e.g. native libs or resources), then you should specify them in this list. See Copy Rules.

Array

No

documentTypes

Array of file association objects. See File Associations.

Array

No

urlSchemes

Array of URL schemes to associate with your app. See URL Schemes.

Array

No

installers

List of the platforms to build installers for when you run jdeploy package. E.g. ["mac", "win", "linux"]. Installers will be built in the jdeploy/installers directory. Not related to the bundles available on the download page. See Building Bundles Locally.

Array

No

None

port

For war deployments, this specifies the port that the Jetty wrapper should bind to. This can be overridden at runtime using the -Djdeploy.port or -Dport command-line flags, or via the PORT environment variable. If this option is omitted, and no port is specified at runtime, it will use "0" as the port, which will cause it to bind to a random open port.

int

No

0

antFile

Set the ant build file to use for the preCopyTarget and postCopyTarget options.

String

No

build.xml

preCopyTarget

You can optionally specify ANT to run a target before copying files to the jdeploy-bundle directory. You can specify the ant build script that contains the target using the antFile property.

String

No

postCopyTarget

Optional ANT target to be run after files have been copied to the jdeploy-bundle directory. You can specify the ant build script that contains the target using the antFile property.

String

No

preCopyScript

Optional script to be executed before copying files to the jdeploy-bundle directory.

String

No

postCopyScript

Optional script to be executed after copying files to the jdeploy-bundle directory.

String

No

Copy Rules

The "jDeploy/files" array includes zero or more copy rules. Each copy rule is an object that may contain the following properties:

Property Description Type Required Default

dir

The relative path to the directory from which files are to be copied.

String

Yes

includes

Specifies files to be included in the copy. Either an array of glob patterns, or a comma-delimited string of glob patterns. The glob pattern uses PathMatcher globs. E.g. "*/.dll".

String or Array

No

All files in dir

excludes

Specifies files to be excluded from the copy. Either an array of glob patterns, or a comma-delimited string of glob patterns. The glob pattern uses PathMatcher globs.

String or Array

No

None

Example Copy Rules*

{
  ...
  "jdeploy" : {
    "files" : [
        {"dir" : "dist", "includes": "lib/*.dll,lib/*.so,lib/*.dylib"}
    ]
  }
  ...
}

This would copy all of the dll, so, and dylib files from "dist/lib" into the jdeploy-bundle directory for deployment.

Automatic jar/war file Resolution

The "jDeploy/jar" and "jDeploy/war" properties specify the location of the jar or war file that constitutes the application. jdeploy init will scan the current directory for eligible jar, war, and web app directories and set the shallowest candidate in the "jDeploy/jar" or "jDeploy/war" directive of the package.json. If you delete this value, or you omit it from the package.json, jdeploy install and jdeploy publish will perform the same search for an appropriate candidate.

Examples

{
  "bin": {"hellojdeploy": "jdeploy-bundle/jdeploy.js"}, // (1)
  "preferGlobal": true, (2)
  "version": "1.0.1",
  "jdeploy": {"jar": "dist/HelloJDeploy.jar"}, (3)
  "dependencies": {"shelljs": "^0.8.4"},
  "license": "ISC",
  "name": "hello-jdeploy", (4)
  "files": ["jdeploy-bundle"] (5)
}
  1. Once installed, the binary name of our app will be "hellojdeploy". I.e. we would start the app by typing "hellojdeploy" at the command prompt.

  2. Indicates that NPM should prefer to install the app globally. If people forget to include the "-g" flag when they try to install the app, they will get a warning.

  3. The executable Jar file that we are deploying is located at "dist/HelloJDeploy.jar".

  4. The command to install the app would be npm install -g jdeploy-bundle

The above package.json deploys an app such that it would be installed with

npm install -g hello-jdeploy

And it would be installed as "hellojdeploy", so that it could be run on the command line:

hellojdeploy

Appendix: Building Executable Jar File

jDeploy essentially converts an executable Jar file into native bundles for Mac, Windows, and Linux. An Executable Jar file is essentially just a Jar file that can be run via java -jar TheJar.jar. The distinguishing feature of an executable jar file (vs a regular jar file) is that it includes directives in its manifest that specify the "Main" class to run, and a "Class-Path" (i.e. a list of dependencies). Most IDEs and build tools have built-in support for generating executable Jar files. In some cases, however, you may need to explicitly enable this.

Executable Jar Files in Maven

The two most common strategies to produce executable jars in Maven are using either a combination of the maven-dependency-plugin and the maven-jar-plugin, or using the maven-assembly-plugin. The latter approach (maven-assembly-plugin) can generate a single "fat" jar with all of your dependencies. The former approach (maven-dependency-plugin and maven-jar-plugin) places your dependencies in a "libs" directory.

I generally prefer the former approach because sometimes bundling everything into a fat jar can break things. Also, when using jDeploy, there is no benefit to a fat jar, since your app is deployed as a native bundle anyways.

Using the maven-dependency-plugin and maven-jar-plugin

In Maven, for example, you will need to use the the maven-dependency-plugin and maven-jar-plugin plugins to package up all the dependencies, and add the appropriate manifest entries to make the jar executable. The following snippet can be added to the <build>/<plugins> section of your pom.xml file.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>
                    ${project.build.directory}/libs
                </outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>libs/</classpathPrefix>
                <mainClass>
                    com.example.YourMainClass
                </mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

You will need to change the <mainClass>com.example.YourMainClass</mainClass> entry to point to the main class of your app.

Using the maven-assembly-plugin

The maven-assembly-plugin is an alternate way to produce an executable jar. It will generate a "fat" jar with all dependencies.

Note
With jDeploy there is no benefit to "fat" jar because your app will be bundled as a native bundle anyways.

The following snippet can be added to the <build>/<plugins> section of your pom.xml file.

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.4</version>
    <executions>
        <execution>
            <id>build-publisher</id>
            <configuration>
                <appendAssemblyId>false</appendAssemblyId>
                <archive>
                    <manifest>
                        <mainClass>com.example.YourMainClass</mainClass>
                    </manifest>
                </archive>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <finalName>${project.artifactId}</finalName>
            </configuration>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>

    </executions>
</plugin>

You will need to change the <mainClass>com.example.YourMainClass</mainClass> entry to point to the main class of your app.