Code Monkey home page Code Monkey logo

capsule's Introduction

Capsule
Dead-Simple Packaging and Deployment for JVM Applications

Build Status Coverage Dependency Status Version License

Capsule is a dead-easy deployment package for standalone JVM applications. Capsule lets you package your entire application into a single JAR file and run it like this java -jar app.jar. That's it. You don't need platform-specific startup scripts, and no JVM flags: the application capsule contains all the JVM configuration options. It supports native libraries, custom boot class-path, and agents. It can automatically download Maven dependencies when the program is first launched if you choose not to embed them in the capsule, and it can even automatically download a new version of your application when it is published to a Maven repository.

In short, a capsule is a self-contained JAR that knows everything there is to know about how to run your application the way it's meant to run.

Cool Stuff You Can Do with Capsules

  • Have your JAR automatically choose an appropriate JVM version, set JVM flags, and add an embedded JAR to the boot class path.
  • Embded any required native libraries directly in the JAR, and Capsule automatically makes sure your application finds them.
  • Distribute your application as an "executable WAR": it can be deployed to a servlet container or, if executed directly, it will automatically download Jetty and deploy itself into the embedded container.
  • Distribute a Clojure application without embedding Clojure itself in the capsule, and have Clojure downloaded the first time the capsule is launched. The Clojure runtime will be cached shared among all Clojure capsules so it will only be downloaded once.
  • Distribute an Avatar.js application as a JAR containing only JavaScript files, and have Avatar (including its required native libraries) downloaded automatically the first time the application is launched. The Avatar runtime will be cached for later use and shared among other Avatar capules.
  • Use a caplet to turn any capsule into a Docker image or to launch it inside a Linux Container.

How Capsule Works

When you include the Capsule class in your JAR file and set it to serve as the JAR's main class, Capsule reads various configuration values (like JVM arguments, environment variables, Maven dependencies and more) from the JAR's manifest. It then downloads all required Maven dependencies, if any, and optionally extracts the JAR's contents into a cache directory. It then picks a JVM installation based on the version requirements in the manifest, and finally, it spawns another JVM process to run your application as configured.

What Capsule Doesn't Do

Capsule doesn't contain a JVM distribution, the application user would need to have a JRE installed. Java 9 is expected to have a mechanism for packaging stripped-down versions of the JVM.

Overhead

A "fat" capsule (one with all dependencies embedded in the capsule JAR), adds about 100ms to the startup time. A "thin" capsule (one with external dependencies, downloaded at first launch), adds about 500ms to the launch time, once the dependencies have been downloaded and cached during the first launch.

In terms of JAR size, fat capsules add negligible overhead, while thin capsules add 1.5MB (for the code responsible to downloading and resolving the external dependencies) -- but they don't require the dependencies to be embedded in the JAR, so there's overall savings in deliverable size.

Alternatives to Capsule

There are a few alternatives to packaging your application in a single JAR. Maven's Shade plugin/Gradle's Shadow plugin rename dependency classes and might interfere with the application in subtle ways; they also don't support native libraries. One-Jar does support native libraries, but uses class-loader hacks that may interfere with the application in even subtler ways. And none of these support JVM arguments. Shade/Shadow, however, are suitable for distributing libraries, while Capsule only works for applications.

The only distribution mechanism supporting JVM arguments and Java version selection is platform-dependent startup scripts. Even if your build tool can generate those for you, they would always require some form of installation by the user.

With Capsule, you just distribute a single JAR and run it.

Getting Capsule

Download

or:

co.paralleluniverse:capsule:0.10.0

on Maven Central.

Building Capsule

./gradlew install

Support

Discuss Capsule on the capsule-user Google Group/Mailing List

Build-Tool Plugins

Maven:

Gradle:

Leiningen:

Usage Examples

Before we delve into the specifics of defining a Capsule distribution, let us look at a few different ways of packaging a capsule. The configurations described below can be built using any JVM build tool. The complete usage example, with both Gradle and Maven build files, is found in the capsule-demo project.

The first example creates what may be called a fat capsule. The capsule JAR has the following structure:

foo.jar
|__ Capsule.class
|__ app.jar
|__ dep1.jar
|__ dep2.jar
\__ MANIFEST
    \__ MANIFEST.MF

With the manifest (MANIFEST.MF) being:

Manifest-Version: 1.0
Main-Class: Capsule
Application-Class: foo.Main
Min-Java-Version: 1.8.0
JVM-Args: -server
System-Properties: foo.bar.option=15 my.logging=verbose
Java-Agents: dep2.jar

We embed the application JAR (app.jar) as well as all dependency JARs into the capsule JAR (without extracting them). We also include the Capsule class in the JAR. Then, in the JAR's manifest, we declare Capsule as the main class. This is the class that will be executed when we run java -jar foo.jar. The Application-Class attribute tells Capsule which class to run in the new JVM process, and we set it to the same value, mainClass used by the build's run task. The Min-Java-Version attribute specifies the JVM version that will be used to run the application. If this version is newer than the Java version used to launch the capsule, Capsule will look for an appropriate JRE installation to use (a maximum version can also be specified with the Java-Version attribute). We then also specify JVM arguments, system properties and even a Java agent.

When we run the capsule with java -jar foo.jar, its contents will be extracted into a cache directory (whose location can be customized).

This kind of capsule has the advantage of being completely self-contained, and it does not require online access to run. The downside is that it can be rather large, as all dependencies are stuffed into the JAR.

The second kind of capsule -- a thin capsule -- does not embed the app's dependencies in the JAR, but downloads them when first run. The capsule JAR looks like this:

foo.jar
|__ Capsule.class
|__ capsule/
|    \__ [capsule classes]
|__ com/
|   \__ acme/
|       \__ [app classes]
\__ MANIFEST/
    \__ MANIFEST.MF

With the manifest being:

Manifest-Version: 1.0
Main-Class: Capsule
Application-Class: foo.Main
Min-Java-Version: 1.8.0
Extract-Capsule : false
JVM-Args: -server
System-Properties: foo.bar.option=15 my.logging=verbose
Dependencies: com.acme:dep1:1.2 com.acme:dep2:3.4
Java-Agents: com.acme:dep2:3.4

This capsule doesn't embed the dependencies in the JAR, so our application's classes can be simply placed in it unwrapped. Instead, the Dependencies attribute declares the application's dependencies. The first time we run java -jar foo.jar, the dependencies will be downloaded (by default from Maven Central, but other Maven repositories may be declared in the manifest). The dependencies are placed in a cache directory shared by all capsules, so common ones like SLF4J or Guava will only be downloaded once. Also, because the app's classes are placed directly in the JAR, and the dependencies are loaded to a shared cache, the capsule does not need to be extracted to the filesystem at all, hence the manifest says Extract-Capsule : false.

Instead of specifying the dependencies and (optionally) the repositories directly in the manifest, if the capsule contains a pom.xml file in the JAR root, it will be used to find the dependencies.

In order to support Maven dependencies, we needed to include all of Capsule's classes in the capsule JAR rather than just the Capsule class. This will add about 1.5MB to the (compressed) JAR, but will save a lot more by not embedding all the dependencies.

Apart from the thin and fat extremes, Capsule supports anything in between: it is possible to embed some dependencies while declaring others in the manifest (or pom.xml) and letting Capsule retrieve them upon first run. Please note that whenever a capsule needs to retrieve even just some Maven artifacts, its JAR needs to include all of Capsule's classes.

Finally, a capsule may not contain any of the application's classes/JARs at all. The capsule's manifest can contain these two attributes:

Main-Class: Capsule
Application: com.acme:foo

And when the capsule is launched, the newest available version of the application will be downloaded, cached and launched. In this use-case, the capsule JAR looks like this:

foo.jar
|__ Capsule.class
|__ capsule/
|    \__ [capsule classes]
\__ MANIFEST/
    \__ MANIFEST.MF

Note how none of the application's classes are actually found in the JAR.

User Guide

A capsule requires two attributes in its manifest file. The first, is the same for all capsules:

Main-Class : Capsule

This attributes makes the JAR file into a capsule. The second attribute tells the capsule what to run when launched. It must be one of:

Application-Class : [the applications's main class, found in the capsule or one of its dependencies]

which specifies the application's main class, or,

Application : [the Maven coordinates of the application's main JAR or the path of the main JAR within the capsule]

or,

Unix-Script    : [a startup script to be run on *nix machines, found in the capsule]
Windows-Script : [a startup script to be run on Windows machines, found in the capsule]

These attributes are sufficient to build a capsule, but there are many other configuration options, which will be explained below.

Launching the Capsule

As mentioned before, java -jar app.jar [app arguments] will launch the application.

The java -Dcapsule.version -jar app.jar command will print the application ID, the version of Capsule used, and then exit without launching the app.

Capsule's JAR can be used standalone (without merging with any application binaries), to launch applications stored in a Maven repository like so:

java -jar capsule.jar com.acme:foo [app arguments]

The above command will download (and cache) the Maven artifact and its dependencies, and run it, provided that it's a capsule itself, or even any executable JAR.

Adding -Dcapsule.log=verbose or -Dcapsule.log=debug before -jar will print information about Capsule's action.

Capsule Configuration and Modes

A capsule is (mostly) configured by attributes in its manifest. Manifest attributes specify which Java version to use when launching the application, what agents to load, the JVM arguments, system properties, dependencies and more.

It is possible to specify different values for each of the configurations -- to be selected at launch time -- by creating several capsule modes. Modes are defined by manifest sections, each section's name corresponds to the mode. Attributes in the manifest's main section are used in the default mode, and those listed in the named sections can override them when the respective node is selected (configurations without overrides will be taken from the main section).

Example:

Attribute-X: foo
Attribute-Y: bar

Name: Special
Attribute-Y: baz

When running in the Special mode, Attribute-Y will have the value baz, while the non-overriden Attribute-X will have the value foo, as in the default mode.

To select a non default mode, you launch the capsule with the -Dcapsule.mode=MODE command line argument.

The Application-Name and Application-Version attributes (see the next section) can only be listed in the manifest's main section.

Application ID

The application ID is used to find the capsule's application cache, where the capsule's contents will be extracted if necessary. If the manifest has an Application-Name, it will be the application's ID, combined with the Application-Version attribute, if found. If there is no Application-Name attribute, and a pom.xml file is found in the JAR's root, the ID will be formed by joining the POM's groupId, artifactId, and version properties. If there is no POM file, the Application-Class attribute will serve as the application name.

When authoring a capsule, please ensure a unique ID by setting Application-Name to a domain-qualified name (e.g. acme.best_app).

Selecting the Java Runtime

Two manifest attributes determine which Java installation Capsule will use to launch the application. Min-Java-Version (e.g. 1.7.0_50 or 1.8.0) is the lowest Java version to use, while Java-Version (e.g. 1.6) is the highest major Java version to use. One, both, or neither of these attributes may be specified in the manifest.

First, Capsule will test the current JVM (used to launch the capsule) against Min-Java-Version and Java-Version (if they're specified). If the version of the current JVM matches the requested range, it will be used to launch the application. If not, Capsule will search for other JVM installations, and use the one with the highest version that matches the requested range. If no matching installation is found, the capsule will fail to launch.

It is also possible to require a minimal update version, say, in cases where the update fixes a bug affecting the application. Because the bug may have been fixed in two different major versions in two different updates (e.g., for Java 7 in update 85, and for Java 8 in update 21), the minimal update required is specified per major Java version, in the Min-Update-Version attribute. For example

Min-Update-Version: 7=85 1.8=21

The major version can be given as a single digit (7) or as a "formal" Java version (1.7, or, 1.7.0). The updates are specified in a whitespace separated list of entries, each entry containing a key (the major version) and a value (the minimum update) as a = separated pair.

If the JDK-Required attribute is set to true, Capsule will only select JDK installations.

Whatever the Min-Java-Version, Java-Version, or JDK-Required attributes specify, launching the capsule with the capsule.java.home system property, will use whatever Java installation is specified by the property, for example: java -Dcapsule.java.home=/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home -jar app.jar.

Finally, setting the capsule.java.cmd system property with the path to the executable which will be used to launch the JVM, overrides any JRE selection mechanism.

Running java -Dcapsule.jvms -jar app.jar will list all Java installations Capsule can find, and then quit without launching the app.

Capsule's Cache

By default, Capsule will extract the capsule JAR's contents -- except for class files placed directly in the JAR -- into a cache directory. If the Extract-Capsule manifest attribute is set to false, the JAR will not be extracted.

The capsule will be extracted once. Following run will compare the JAR's modification date with that of the cache, and will re-write the cache only if the capsule JAR is younger. You can force re-extraction of the capsule with -Dcapsule.reset=true.

The location of the cache and the location of the JAR are communicated to the application through the capsule.dir and capsule.jar system properties respectively. Capsule defines these properties automatically, and the application may use them, for example, to find extracted resources. In addition, those two filesystem paths can be used within the manifest itself to set various values (system properties, environment variables, etc) by referencing them with $CAPSULE_DIR and $CAPSULE_JAR respectively.

Using the values in capsule.dir or CAPSULE_DIR to directly access the cache is generally discouraged, and should be a last resort (but a working one, nonetheless), as it depends on Capsule's inner workings.

Capsule's cache is found, by default, at ~/.capsule/ on Unix/Linux/Mac OS machines, and at %USERPROFILE%\AppData\Local\capsule\ on Windows. The application caches are placed in the apps/APP_ID subdirectory of the cache, while the shared dependency cache is at the deps subdirectory. The location of the Capsule cache can be changed with environment variables: setting CAPSULE_CACHE_NAME determines the name of the topmost Capsule cache dir (i.e. "capsule" by default), while CAPSULE_CACHE_DIR can be used to set a precise path for the cache (e.g. `/tmp/capsule/).

Maven Dependencies

The capsule can specify external dependencies as coordinates in Maven repositories. One way of specifying dependencies, is placing the app's pom.xml file in the capsule JAR's root. Another is specifying the dependencies and repositories in the capsule's manifest.

By default, Capsule will look for dependencies on Maven Central. If other repositories are needed (or if you don't want to access Maven Central), the Repositories attribute is a space-separated list of Maven repositories formatted as URL or NAME(URL). The repositories will be searched in the order they are listed. If the Repositories attribute is found in the manifest, then Maven Central will not be searched.

Instead of specifying explicit URLs, the following well-known repository names can be listed in the Repositories attribute:

  • central - Maven central, HTTPS
  • central-http - Maven central, HTTP
  • jcenter - jCenter, HTTPS
  • jcenter-http - jCenter, HTTP
  • local - Default local Maven repository (userdir/.m2/repository). You should only use local repositories in tests.

Capsule also automatically uses the information in Maven's settings.xml file to access repositories that require authentication. The settings.xml used is the user's settings (in the .m2 directory in the user's home directory), or in the global settings (in the conf subdirectory of the Maven installation). A settings.xml file is absolutely not required for Capsule's operation, and is mostly useful when accessing private organizational Maven repositories for dependencies.

The dependencies, (if not read from the POM), are listed in the Dependencies attribute, as a space-separated list of Maven coordinates in the Gradle format, i.e. groupId:artifactId:version. Exclusions can be given as a comma separated list within parentheses, immediately following the main artifact, of groupId:artifactId coordinates, where the artifact can be the wildcard *. For example:

Dependencies : com.esotericsoftware.kryo:kryo:2.23.0(org.ow2.asm:*)

The dependencies are downloaded the first time the capsule is launched, and placed in the deps subdirectory of the Capsule cache, where they are shared among all capsules.

The CAPSULE_REPOS environment variable can be set to a comma- (,) or a whitespace-separated list of Maven repository URLS or well-known repository names (see above), which will be prepended to those specified in the manifest or the POM.

By default, SNAPSHOT dependencies are not allowed, unless the Allow-Snapshots is set to true.

Capsule can make use of Maven repositories in another way: the Application manifest attribute can specify the Maven coordinates of the application's main JAR file, which can in itself be a capsule.

Maven version ranges (as well as LATEST and RELEASE) are supported. For example: Application: com.acme:foo:[1.0,2.0). The newest version matching the range (or the newest version if no range is given), will be downloaded, cached and launched. Not specifying a version at all will resolve to the latest release. If the application's main artifact is a capsule, then all configurations will be taken based on those in the artifact capsule.

Native dependencies can be specified in the Native-Dependencies-Linux/Native-Dependencies-Win/Native-Dependencies-Mac attributes, each for its respective OS. A native dependency is written as a plain dependency but can be followed by an equal-sign and a new filename to give the artifact once downloaded (e.g.: com.acme:foo-native-linux-x64:1.0,foo-native.so). Each native artifact must be a single native library, with a suffix matching the OS (.so for Linux, .dll for windows, .dylib for Mac). The native libraries are downloaded and copied into the application cache (and renamed if requested).

Adding -Dcapsule.reset=true, can force a re-download of SNAPSHOT versions.

The command: java -Dcapsule.tree -jar app.jar, will print the dependency tree for the capsule, and then quit without launching the app.

Two more system properties affect the way Capsule searches for dependencies. If capsule.offline is defined or set to true (-Dcapsule.offline or -Dcapsule.offline=true), Capsule will not attempt to contact online repositories for dependencies (instead, it will use the local Maven repository/cache only). capsule.local determines the path for the local Maven repository/cache Capsule will use (which, by default, is the deps subdirectory of the Capsule cache).

Class Paths

By default, Capsule sets the application's class path to: the capsule JAR itself, the application's cache directory (if the capsule is extracted) and every JAR found in the root of the cache directory (i.e. every JAR file placed in the capsule JAR's root) -- in no particular order -- and, finally, the application's Maven dependencies in the order they are listen in the Dependencies attribute or the POM file. Also, if the capsule contains an Application attribute, all entries in the Class-Path attribute in the manifest of the Application JAR are added to the classpath automatically.

The classpath, however, can be customized by the Class-Path attribute, which can be given an ordered (space separated) list of JARs and/or directories relative to the capsule JAR root. This attribute only applies if the capsule is extracted, and if it is found in the manifest, then all JARs in the cache's root will not be added automatically to the classpath.

In addition to setting the application classpath, you can also specify the boot classpath. The Boot-Class-Path attribute is, similar to the Class-Path attribute, an ordered, space separated list of JARs and/or directories relative to the capsule's root, that will become the application's boot classpath. If you don't want to replace the default Java boot classpath, but simply to tweak it, The Boot-Class-Path-P attribute can be used to specify a classpath to be prepended to the default boot classpath, and the Boot-Class-Path-P attribute can specify a class path that will be appended to the default.

If the capsule is launched with a -Xbootclasspath option, it will override any setting by the capsule's manifest.

The Library-Path-A manifest attribute can list JARs or directories (relative to the capsule's root) that will be appended to the application's native library path. Similarly, Library-Path-P, can be used to prepend JARs or directories to the default native library path.

JVM Arguments, System Properties, Environment Variables and Agents

The JVM-Args manifest attribute can contain a space-separated list of JVM argument that will be used to launch the application. Any JVM arguments supplied during the capsule's launch, will override those in the manifest. For example, if the JVM-Args attribute contains -Xmx500m, and the capsule is launched with java -Xmx800m -jar app.jar, then the application will be launched with the -Xmx800m JVM argument.

JVM arguments listed on the command line apply both to the Capsule launch process as well as the application process (see The Capsule Execution Process). Sometimes this is undesirable (e.g. when specifying a debug port, which can only apply to a single process or a port collision will ensue). JVM arguments for at the application process (only) can be supplied by adding -Dcapsule.jvm.args="MY JVM ARGS" to the command line.

The Args manifest attribute can contain a space-separated list of command line arguments to be passed to the application; these will be prepended to any arguments passed to the capsule at launch.

The System-Properties manifest attribute can contain a space-separated list of system properties that will be defined in the launched application. The properties are listed as property=value pairs (or just property for an empty value). Any system properties supplied during the capsule's launch, will override those in the manifest. For example, if the JVM-Args attribute contains name=Mike, and the capsule is launched with java -Dname=Jason -jar app.jar, then the application will see the name system-property defined as Jason.

The Environment-Variables manifest attribute, is, just like System-Properties, a space-separated list of var=value pairs (or just var for an empty value). The specified values do not overwrite those already defined in the environment, unless they are listed as var:=value rather than var=value.

The Java-Agents attribute can contain a space-separated list with the names of JARs containing Java agents. The agents are listed as agent=params or just agent, where agent is either the path of a JAR embedded in the capsule, relative to the capsule JAR's root, or the coordinates of a Maven dependency.

Similarly, the Native-Agents attribute may contain a list of native JVMTI agents to be used by the application. The formatting is the same as that for Java-Agents, except that agent is the path to the native library -- minus the extension -- relative to the capsule root. Unlike in the case of Java-Agents, listing Maven dependencies is not allowed, but the same result can be achieved by listing the depndencies in the Native-Dependencies-... attributes and then referring to the library file's name in the Native-Agents attribute.

Remember that values listed in all these configuration values can contain the $CAPSULE_DIR and $CAPSULE_JAR variables, discussed in the Capsule's Cache section.

Scripts

While Capsule mostly makes startup scripts unnecessary, in some circumstances they can be useful. Capsule allows placing platform-specific scripts into the capsule JAR, and executing them instead of launching a JVM and running Application-Class. The Unix-Script attribute specifies the location (relative to the capsule JAR's root) of a POSIX shell script, to be run on POSIX machines, while Windows-Script specifies the location of a Windows script file. If only, say, Unix-Script is defined, then on Windows machines Capsule will simply run the Application-Class as usual.

The scripts can make use of the CAPSULE_DIR environment variable to locate capsule files. In addition, Capsule will choose the JVM installation based on the version requirements, and set the JAVA_HOME environment variable for the script appropriately.

Scripts cannot be used if the Extract-Capsule attribute is false.

Security Manager

The Security-Policy attribute specifies a Java security policy file to use for the application. Its value is the location of the security file relative to the capsule JAR root. The Security-Policy-A achieves a similar purpose, only the security policy specified is added to the default one rather than replaces it. Finally, the Security-Manager attribute can specify a class to be used as the security manager for the application.

If any of these three properties is set, a security manager will be in effect when the application runs. If the Security-Manager attribute is not set, the default security manager will be used.

Caplets

You can customize many of the capsule's inner workings by creating a Caplet -- custom capsule. A caplet is a subclass of Capsule that overrides some of its overridable methods.

To apply the caplets to the capsule you list them, in the order they're to be applied, in the Caplets manifest attribute. You can either embed a caplet in your capsule, in which case list its class name in the Caplet attribute, or declare it as an external Maven dependency and list it's artifact coordinates.

Please consult Capsule's Javadoc for specific documentation on custom capsules.

Some experimental and very-much-unfunished, yet interesting, caplets are:

Empty Capsules and Capsule Wrapping

A capsule that contains no application (i.e., it's manifest has no Application-Class, Application, Application-Name etc.) is known as an empty capsule. Most caplets and, in fact, the Capsule project itself, are shipped as binaries which are essentially empty capsules. While you cannot run an empty capsule on its own, empty capsules can serve -- unmodified -- as capsule wrappers that wrap other capsules, or even un-capsuled applications. This is most useful when the empty, wrapper, capsule employs caplets to provide some special behavior to the wrapped capsule or application.

Suppose capsule.jar is an empty capsule. We can use it to launch an application stored in a Maven repository like so:

java -jar capsule.jar com.acme:coolapp

Or, if the application is stored in a local JAR:

java -jar capsule.jar coolapp.jar

In both cases, the only requirement from coolapp is that it has a main class declared in its manifest.

If coolapp is a capsule rather than a simple application, then our empty capsule will be used as a caplet which will be applied to the wrapped capsule.

"Really Executable" Capsules

A JAR file can be made "really executable" in UNIX/Linux/MacOS environments -- i.e. it can be run simply as capsule.jar ARGS rather than java -jar capsule.jar ARGS -- by prepending a couple of shell script lines to the JAR (it turns out JAR files can tolerate any prepended headers).

Both capsule-maven-plugin and gradle-capsule-plugin support creation of really executable capsules simply by setting a flag.

If you choose not to use one of the capsule plugins, then you can use the really-executable-jars Maven plugin to make your capsule really executable (or if you're using the capsule-maven-plugin, just set the buildExec tag to true). In Gradle, this can be done by adding the following function to your build file:

def reallyExecutable(jar) {
    ant.concat(destfile: "tmp.jar", binary: true) {
        zipentry(zipfile: configurations.capsule.singleFile, name: 'capsule/execheader.sh')
        fileset(dir: jar.destinationDir) {
            include(name: jar.archiveName)
        }
    }
    copy {
        from 'tmp.jar'
        into jar.destinationDir
        rename { jar.archiveName }
    }
    delete 'tmp.jar'
}

and then

capsule.doLast { task -> reallyExecutable(task) }

The Capsule Execution Process

When a capsule is launched, two processes are involved: first, a JVM process runs the capsule launcher, which then starts up a second, child process that runs the actual application. The two processes are linked so that killing or suspending one, will do the same for the other. On UNIX systems (Linux, Mac, etc.), the launcher process makes public the identity of the child process by setting the capsule.app.pid system property, which can be queried with the jcmd command. Suppose the capsule's pid is 1234, then the child (app) process pid can be obtained with the following shell command:

jcmd 1234 VM.system_properties  | grep capsule.app.pid | cut -f 2 -d =

While this model works well enough in most scenarios, sometimes it is desirable to directly launch the process running the application, rather than indirectly. This is supported by "capsule trampoline", and is available for really executable capsules on UNIX systems only. To take advantage of capsule trampolining, use the capsule/trampoline-execheader.sh executable header (rather than capsule/execheader.sh) when creating the really executable capsule.

capsule-util

The capsule-util sub-project contains classes to create and interact with capsule's at runtime. See the Javadocs here.

capsule-build

The capsule-build sub-project contains utilities used by build-tool plugins that create capsules. See the Javadocs here.

Reference

Manifest Attributes

Everywhere the word "list" is mentioned, it is whitespace-separated.

  • Application-Name: the name of the application, used to define its ID
  • Application-Version: the application's version, used to define its ID
  • Application-Class: the application's main class
  • Application: the Maven coordinates of the application's main JAR or the path of the main JAR within the capsule
  • Unix-Script: a startup script to be run instead of Application-Class on Unix/Linux/Mac OS, given as a path relative to the capsule's root
  • Windows-Script: a startup script to be run instead of Application-Class on Windows, given as a path relative to the capsule's root
  • Extract-Capsule: if false, the capsule JAR will not be extracted to the filesystem (default: true)
  • Min-Java-Version: the lowest Java version required to run the application; Capsule will look for an appropriate installation
  • Min-Update-Version: a space-separated key-value ('=' separated) list mapping Java versions to the minimum update version required
  • Java-Version: the highest version of the Java installation required to run the application; Capsule will look for an appropriate installation
  • JDK-Required: if set to true, the Capsule will only be launched using a JDK, if one matching the requested versions is found.
  • JVM-Args: a list of JVM arguments that will be used to launch the application's Java process
  • Args: the list of command line arguments to be passed to the application; the UNIX shell-style special variables ($*, $1, $2, ...) can refer to the actual arguments passed on the capsule's command line; if no special var is used, the listed values will be prepended to the supplied arguments (i.e., as if $* had been listed last).
  • Environment-Variables: a list of environment variables that will be put in the applications environment; formatted var=value or var
  • System-Properties: a list of system properties that will be defined in the applications JVM; formatted prop=value or prop
  • App-Class-Path: a list of JARs, relative to the capsule root, that will be put on the application's classpath, in the order they are listed
  • Capsule-In-Class-Path: if set to false, the capsule JAR itself will not be on the application's classpath (default: true)
  • Boot-Class-Path: a list of JARs, dependencies, and/or directories, relative to the capsule root, that will be used as the application's boot classpath.
  • Boot-Class-Path-A: a list of JARs dependencies, and/or directories, relative to the capsule root, that will be appended to the applications default boot classpath
  • Boot-Class-Path-P: a list of JARs dependencies, and/or directories, relative to the capsule root, that will be prepended to the applications default boot classpath
  • Library-Path-A: a list of JARs and/or directories, relative to the capsule root, that will be appended to the default native library path
  • Library-Path-P: a list of JARs and/or directories, relative to the capsule root, that will be prepended to the default native library path
  • Security-Manager: the name of a class that will serve as the application's security-manager
  • Security-Policy: a security policy file, relative to the capsule root, that will be used as the security policy
  • Security-Policy-A: a security policy file, relative to the capsule root, that will be appended to the default security policy
  • Java-Agents: a list of Java agents used by the application; formatted agent or agent=arg1,arg2..., where agent is either the path to a JAR relative to the capsule root, or a Maven coordinate of a dependency
  • Native-Agents: a list of native JVMTI agents used by the application; formatted "agent" or "agent=arg1,arg2...", where agent is either the path to a native library, without the platform-specific suffix, relative to the capsule root; the native library file(s) can be embedded in the capsule or listed as Maven native dependencies using the Native-Dependencies-... attributes.
  • Repositories: a list of Maven repositories formatted as URL or NAME(URL)
  • Dependencies: a list of Maven dependencies given as groupId:artifactId:version[(excludeGroupId:excludeArtifactId,...)]
  • Allow-Snapshots: If true, allows for SNAPSHOT dependencies (default: false)
  • Native-Dependencies-Linux: a list of Maven dependencies consisting of .so artifacts for Linux; each item can be a key-value pair ('=' separated), with the second component being a new name to give the download artifact. The artifacts will be downloaded and copied into the application's cache directory.
  • Native-Dependencies-Win: a list of Maven dependencies consisting of .dll artifacts for Linux; each item can be a key-value pair ('=' separated), with the second component being a new name to give the download artifact. The artifacts will be downloaded and copied into the application's cache directory.
  • Native-Dependencies-Mac: a list of Maven dependencies consisting of .dylib artifacts for Mac OS X; each item can be a key-value pair ('=' separated), with the second component being a new name to give the download artifact. The artifacts will be downloaded and copied into the application's cache directory.
  • Capsule-Log-Level: sets the default log level for the Capsule launcher (which can be overridden with -Dcapsule.log); can be one of: NONE, QUIET (the default), VERBOSE, or DEBUG.
  • Caplets: a list of names of caplet classes -- if embedded in the capsule -- or Maven coordinates of caplet artifacts that will be applied to the capsule in the order they are listed.

Manifest Variables

  • $CAPSULE_JAR: the full path to the capsule JAR
  • $CAPSULE_DIR: the full path to the application cache directory, if the capsule is extracted.
  • $JAVA_HOME: the full path to the Java installation which will be used to launch the app

System Properties

  • capsule.version: if set, the capsule will print the application ID, its Capsule version and quit without launching the app
  • capsule.tree: if set, the capsule will print the app's dependency tree, and then quit without launching the app
  • capsule.jvms: if set, the capsule will print the JVM installations it can locate with their versions, and then quit without launching the app
  • capsule.resolve: all external dependencies, if any, will be downloaded (if not cached already), and/or the capsule will be extracted if necessary, but the application will not be launched
  • capsule.mode: if set, the capsule will be launched in the specified mode (see Capsule Configuration and Modes)
  • capsule.log: can be set to 'none'/'quiet' (default)/'verbose'/'debug'
  • capsule.jvm.args: specifies JVM arguments for the capsule's app process.
  • capsule.reset: if set, forces re-extraction of the capsule, where applies, and/or re-downloading of SNAPSHOT dependencies
  • capsule.java.home: forces the capsule to use the given path to a Java installation when launching the application.
  • capsule.java.cmd: firces the capsule to use the give executable to launch the JVM.
  • capsule.offline: if defined (without a value) or set to true, Capsule will not attempt to contact online repositories for dependencies
  • capsule.local: the path for the local Maven repository; defaults to CAPSULE_CACHE/deps
  • capsule.connect.timeout: The maximum amount of time (in milliseconds) to wait for a successful connection to a remote repository. Non-positive values indicate no timeout.
  • capsule.request.timeout: The maximum amount of time (in milliseconds) to wait for remaining data to arrive from a remote repository. Note that this timeout does not restrict the overall duration of a request, it only restricts the duration of inactivity between consecutive data packets. Non-positive values indicate no timeout.

Capsule defines these system properties in the application's process:

  • capsule.app: the app ID
  • capsule.jar: the full path to the capsule's JAR
  • capsule.dir: if the JAR has been extracted, the full path of the application cache (use generally discouraged).

Capsule defines these system properties in the capsule (launcher) process (to be queried by jcmd):

  • capsule.app.pid: the child (application) process PID; available only in POSIX environments.

Environment Variables

  • CAPSULE_CACHE_NAME: sets the name of the root of Capsule's cache in the default location (~ on Unix, %LOCALAPPDATA% on Windows)
  • CAPSULE_CACHE_DIR: sets the full path of the Capsule's cache
  • CAPSULE_REPOS: sets the list -- comma (,) or whitespace separated -- of Maven repositories that the capsule will use; overrides those specified in the manifest or the POM.
  • CAPSULE_CONNECT_TIMEOUT: The maximum amount of time (in milliseconds) to wait for a successful connection to a remote repository. Non-positive values indicate no timeout.
  • CAPSULE_REQUEST_TIMEOUT: The maximum amount of time (in milliseconds) to wait for remaining data to arrive from a remote repository. Note that this timeout does not restrict the overall duration of a request, it only restricts the duration of inactivity between consecutive data packets. Non-positive values indicate no timeout.

Capsule defines these variables in the application's environment:

  • CAPSULE_APP: the app ID
  • CAPSULE_JAR: the full path to the capsule's JAR
  • CAPSULE_DIR: if the JAR has been extracted, the full path of the application cache.

These values can also be accessed with $VARNAME in any capsule manifest attributes.

Javadoc

License

Copyright (c) 2014, Parallel Universe Software Co. and Contributors. All rights reserved.

This program and the accompanying materials are licensed under the terms
of the Eclipse Public License v1.0 as published by the Eclipse Foundation.

    http://www.eclipse.org/legal/epl-v10.html

As Capsule does not link in any way with any of the code bundled in the JAR file, and simply treats it as raw data, Capsule is no different from a self-extracting ZIP file (especially as manually unzipping and examining the JAR's contents is extremely easy). Capsule's own license, therefore, does not interfere with the licensing of the bundled software.

In particular, even though Capsule's license is incompatible with the GPL/LGPL, it is permitted to distribute GPL programs packaged as capsules, as Capsule is simply a packaging medium and an activation script, and does not restrict access to the packaged GPL code. Capsule does not add any capability to, nor removes any from the bundled application. It therefore falls under the definition of an "aggregate" in the GPL's terminology.

capsule's People

Contributors

bellinha avatar circlespainter avatar colemanserious avatar danthegoodman avatar davidmc24 avatar fbaro avatar pron avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.