JAR(1)

πŸ“¦ version 17.0.19.0, in opensuse-leap 16.0

πŸ«™ JAR(1) β€” the jar command, bestie edition ✨

okay so this is the JDK Commands family's very own jar page, and I'm gonna walk you through it like we're texting at 2am πŸ’–

🌸 NAME 🌸

jar β€” creates an archive for classes and resources, and manipulates or restores individual classes or resources from an archive πŸŽ€

πŸ¦‹ SYNOPSIS πŸ¦‹

jar [OPTION ...] [ [--release VERSION] [-C dir] files] ...

✨ DESCRIPTION ✨

So jar? It's a general-purpose archiving and compression tool, built on the ZIP and ZLIB compression formats, no cap πŸ’…

Back in the day it was designed to package Java applets (which, side note, are not supported since JDK 11, rip) or applications. But starting with JDK 9, users can use jar to create modular JARs. And for transportation and deployment purposes, it's usually way more convenient to package modules as modular JARs β€” that's just the move 🫢

The syntax for jar honestly resembles the syntax for the tar command, iykyk. It has several main operation modes, defined by one of the mandatory operation arguments. Any other arguments are either options that modify the behavior of the operation, or they're required to actually perform the operation.

Here's the glow-up: when modules or the components of an application (files, images and sounds) get combined into a single archive, they can be downloaded by a Java agent (like a browser) in a single HTTP transaction instead of needing a whole new connection for each piece. That dramatically improves download times, periodt. And jar also compresses files, which further improves download time πŸ”₯ It also enables individual entries in a file to be signed so their origin can be authenticated. A JAR file can be used as a class path entry, whether or not it's compressed. iconic.

An archive becomes a modular JAR when you include a module descriptor, module-info.class, in the root of the given directories, or in the root of the .jar archive. The following operations described in Operation Modifiers Valid Only in Create and Update Modes are valid only when creating or updating a modular jar, or updating an existing non-modular jar:

  • --module-version
  • --hash-modules
  • --module-path
Note: All mandatory or optional arguments for long options are also mandatory or optional for any corresponding short options. πŸ’€ like, the long version doesn't get to be lazier than the short one.

πŸ‘‘ MAIN OPERATION MODES πŸ‘‘

When you're using the jar command, you must specify the operation for it to perform β€” no main character mode without picking a mode, bestie. You specify the operation mode by including the appropriate operation arguments described in this section. You can mix an operation argument with other one-letter options too. And generally? The operation argument is the first argument specified on the command line.

  • -c or --create β€” Creates the archive πŸ—οΈ
  • -i=FILE or --generate-index=FILE β€” Generates index information for the specified JAR file.
  • -t or --list β€” Lists the table of contents for the archive πŸ“‹
  • -u or --update β€” Updates an existing JAR file.
  • -x or --extract β€” Extracts the named (or all) files from the archive.
  • -d or --describe-module β€” Prints the module descriptor or automatic module name 🧐

πŸ’œ OPERATION MODIFIERS VALID IN ANY MODE πŸ’œ

You can use the following options to customize the actions of any operation mode included in the jar command. versatile queens only πŸ’…

  • -C DIR β€” Changes the specified directory and includes the files specified at the end of the command line.
jar [OPTION ...] [ [--release VERSION] [-C dir] files]
  • -f=FILE or --file=FILE β€” Specifies the archive file name.
  • --release VERSION β€” Creates a multirelease JAR file. Places all files specified after the option into a versioned directory of the JAR file named META-INF/versions/VERSION/, where VERSION must be a positive integer whose value is 9 or greater. ⚠️

At run time, where more than one version of a class exists in the JAR, the JDK will use the first one it finds, searching initially in the directory tree whose VERSION number matches the JDK's major version number. It will then look in directories with successively lower VERSION numbers, and finally look in the root of the JAR. (search order: newest match β†’ older matches β†’ root, no shortcuts 🧚)

  • -v or --verbose β€” Sends or prints verbose output to standard output πŸ—£οΈ

πŸŽ€ OPERATION MODIFIERS VALID ONLY IN CREATE AND UPDATE MODES πŸŽ€

You can use the following options to customize the actions of the create and the update main operation modes:

  • -e=CLASSNAME or --main-class=CLASSNAME β€” Specifies the application entry point for standalone applications bundled into a modular or executable modular JAR file πŸšͺ
  • -m=FILE or --manifest=FILE β€” Includes the manifest information from the given manifest file.
  • -M or --no-manifest β€” Doesn't create a manifest file for the entries. (yes, the absence is the point πŸ™ˆ)
  • --module-version=VERSION β€” Specifies the module version, when creating or updating a modular JAR file, or updating a non-modular JAR file.
  • --hash-modules=PATTERN β€” Computes and records the hashes of modules matched by the given pattern and that depend upon directly or indirectly on a modular JAR file being created or a non-modular JAR file being updated.
  • -p or --module-path β€” Specifies the location of module dependence for generating the hash.
  • @file β€” Reads jar options and file names from a text file as if they were supplied on the command line πŸ“„

πŸ¦‹ OPERATION MODIFIERS VALID ONLY IN CREATE, UPDATE, AND GENERATE-INDEX MODES πŸ¦‹

You can use the following options to customize the actions of the create (-c or --create), the update (-u or --update), and the generate-index (-i or --generate-index=FILE) main operation modes:

  • -0 or --no-compress β€” Stores without using ZIP compression. (yes it's a zero, and yes it means "no squeeze" πŸ‹)

🌈 OTHER OPTIONS 🌈

The following options are recognized by the jar command and are not used with operation modes:

  • -h or --help[:compat] β€” Displays the command-line help for the jar command, or optionally the compatibility help πŸ†˜
  • --help-extra β€” Displays help on extra options.
  • --version β€” Prints the program version.

🌟 EXAMPLES OF JAR COMMAND SYNTAX 🌟

  • Create an archive, classes.jar, that contains two class files, Foo.class and Bar.class.
jar --create --file classes.jar Foo.class Bar.class
  • Create an archive, classes.jar, by using an existing manifest, mymanifest, that contains all of the files in the directory foo/.
jar --create --file classes.jar --manifest mymanifest -C foo/
  • Create a modular JAR archive, foo.jar, where the module descriptor is located in classes/module-info.class.
jar --create --file foo.jar --main-class com.foo.Main --module-version 1.0 -C foo/classes resources
  • Update an existing non-modular JAR, foo.jar, to a modular JAR file.
jar --update --file foo.jar --main-class com.foo.Main --module-version 1.0 -C foo/module-info.class
  • Create a versioned or multi-release JAR, foo.jar, that places the files in the classes directory at the root of the JAR, and the files in the classes-10 directory in the META-INF/versions/10 directory of the JAR. πŸ—‚οΈ

In this example, the classes/com/foo directory contains two classes, com.foo.Hello (the entry point class) and com.foo.NameProvider, both compiled for JDK 8. The classes-10/com/foo directory contains a different version of the com.foo.NameProvider class β€” this one containing JDK 10 specific code and compiled for JDK 10.

Given this setup, create a multirelease JAR file foo.jar by running the following command from the directory containing the directories classes and classes-10.

jar --create --file foo.jar --main-class com.foo.Hello -C classes . --release 10 -C classes-10 .

The JAR file foo.jar now contains:

% jar -tf foo.jar

META-INF/
META-INF/MANIFEST.MF
com/
com/foo/
com/foo/Hello.class
com/foo/NameProvider.class
META-INF/versions/10/com/
META-INF/versions/10/com/foo/
META-INF/versions/10/com/foo/NameProvider.class

As well as other information, the file META-INF/MANIFEST.MF will contain the following lines to indicate that this is a multirelease JAR file with an entry point of com.foo.Hello.

...
Main-Class: com.foo.Hello
Multi-Release: true

Assuming that the com.foo.Hello class calls a method on the com.foo.NameProvider class, running the program using JDK 10 will ensure that the com.foo.NameProvider class is the one in META-INF/versions/10/com/foo/. Running the program using JDK 8 will ensure that the com.foo.NameProvider class is the one at the root of the JAR, in com/foo. 🧠✨

  • Create an archive, my.jar, by reading options and lists of class files from the file classes.list.
Note: To shorten or simplify the jar command, you can specify arguments in a separate text file and pass it to the jar command with the at sign (@) as a prefix. To shorten or simplify the jar command, you can provide an arg file that lists the files to include in the JAR file and pass it to the jar command with the at sign (@) as a prefix.
jar --create --file my.jar @classes.list
⚠️ If one or more entries in the arg file cannot be found, then the jar command fails without creating the JAR file. like it's not gonna half-do it for you, bestie πŸ’€

and that's the whole page!! πŸŽ‰ this one's from JDK 17, dated 2021, and it lives under the JAR(1) name in the JDK Commands section β€” go forth and archive responsibly, ily πŸ«ΆπŸ’–βœ¨

πŸ“¦ where this page comes from
  • opensuse-leap 16.0: java-17-openj9-devel 17.0.19.0-bp160.1.1 Β· Apache-1.1 AND Apache-2.0 AND EPL-2.0 AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-only WITH Classpath-exception-2.0 AND LGPL-2.0-only AND MPL-1.0 AND MPL-1.1 AND LicenseRef-SUSE-Public-Domain AND W3C
  • opensuse-leap 16.0: java-17-openj9-devel 17.0.19.0-bp160.1.1 Β· Apache-1.1 AND Apache-2.0 AND EPL-2.0 AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-only WITH Classpath-exception-2.0 AND LGPL-2.0-only AND MPL-1.0 AND MPL-1.1 AND LicenseRef-SUSE-Public-Domain AND W3C
  • opensuse-leap 16.0: java-17-openj9-devel 17.0.19.0-bp160.1.1 Β· Apache-1.1 AND Apache-2.0 AND EPL-2.0 AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-only WITH Classpath-exception-2.0 AND LGPL-2.0-only AND MPL-1.0 AND MPL-1.1 AND LicenseRef-SUSE-Public-Domain AND W3C
  • opensuse-leap 16.0: java-17-openj9-devel 17.0.19.0-bp160.1.1 Β· Apache-1.1 AND Apache-2.0 AND EPL-2.0 AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-only WITH Classpath-exception-2.0 AND LGPL-2.0-only AND MPL-1.0 AND MPL-1.1 AND LicenseRef-SUSE-Public-Domain AND W3C
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms