Typically, verification of signed JAR files will be the responsibility of your JavaTM Runtime Environment. Your browser will verify signed applets that it downloads. Signed applications invoked with the -jar option of the interpreter will be verified by the runtime environment.
However, you can verify signed JAR files yourself by using the Jarsigner tool. You might want to do this, for example, to test a signed JAR file that you’ve prepared.
The basic command to use for verifying a signed JAR file is:
jarsigner -verify jar-file
This command will verify the JAR file’s signature and ensure that the files in the archive haven’t changed since it was signed. You’ll see the following message if the verification is successful:
jar verified.
If you try to verify an unsigned JAR file, the following message results:
jar is unsigned. (signatures missing or not parsable)
If the verification fails, an appropriate message is displayed. For example, if the contents of a JAR file have changed since the JAR file was signed, a message similar to the following will result if you try to verify the file:
jarsigner: java.lang.SecurityException: invalid SHA1
signature file digest for test/classes/Manifest.class
Author: strong
Signing and Verifying JAR Files
You can optionally sign a JAR file with your electronic “signature.” Users who verify your signature can grant your JAR-bundled software security privileges that it wouldn’t ordinarily have. Conversely, you can verify the signatures of signed JAR files that you want to use.
This lesson shows you how to use the tools provided in the JavaTM Development Kit to sign and verify JAR files:
Understanding Signing and Verification
If you’re not familiar with the concepts of signing and verification, this section will help to bring you up to speed. It contains definitions of the relevant terms, explanations of some of the benefits provided by signing, and an outline of the signing mechanism used by the Java platform as it relates to JAR files.
Signing JAR Files
In this section, you’ll learn how to use the JDKTM tools to digitally sign your JAR files.
Verifying Signed JAR Files
This section shows you how to use the JDK tool set to verify signed JAR files.
Understanding the Default Manifest
When you create a JAR file, it automatically receives a default manifest file. There can be only one manifest file in an archive, and it always has the pathname
META-INF/MANIFEST.MF
When you create a JAR file, the default manifest file simply contains the following:
Manifest-Version: 1.0Created-By: 1.6.0 (Sun Microsystems Inc.)
These lines show that a manifest`s entries take the form of “header: value” pairs. The name of a header is separated from its value by a colon. The default manifest conforms to version 1.0 of the manifest specification and was created by the 1.6.0 version of the JDK.
The manifest can also contain information about the other files that are packaged in the archive. Exactly what file information should be recorded in the manifest depends on how you intend to use the JAR file. The default manifest makes no assumptions about what information it should record about other files.
Digest information is not included in the default manifest. To learn more about digests and signing, see the Signing and Verifying JAR Files lesson.
Sealing Packages within a JAR File
Packages within JAR files can be optionally sealed, which means that all classes defined in that package must be archived in the same JAR file. You might want to seal a package, for example, to ensure version consistency among the classes in your software.
You seal a package in a JAR file by adding the Sealed header in the manifest, which has the general form:
The value myCompany/myPackage/ is the name of the package to seal.Name: myCompany/myPackage/
Sealed: true
Note that the package name must end with a “/”.
An Example
We want to seal two packages firstPackage and secondPackage in the JAR file MyJar.jar.
We first create a text file named Manifest.txt with the following contents:
Name: myCompany/firstPackage/
Sealed: trueName: myCompany/secondPackage/
Sealed: true
We then create a JAR file named MyJar.jar by entering the following command:
Warning :
The text file must end with a new line or carriage return. The last line will not be parsed properly if it does not end with a new line or carriage return.
This creates the JAR file with a manifest with the following contents:jar cmf MyJar.jar Manifest.txt MyPackage/*.class
Manifest-Version: 1.0
Created-By: 1.6.0 (Sun Microsystems Inc.)
Name: myCompany/firstPackage/
Sealed: true
Name: myCompany/secondPackage/
Sealed: true
Sealing JAR Files
If you want to guarantee that all classes in a package come from the same code source, use JAR sealing. A sealed JAR specifies that all packages defined by that JAR are sealed unless overridden on a per-package basis.
To seal a jar file, use the Sealed manifest header with the value true. For example,
specifies that all packages in this archive are sealed unless explicitly overridden for particular packages with the Sealed attribute in a manifest entry.Sealed: true
Modifying a Manifest File
You use the m command-line option to add custom information to the manifest during creation of a JAR file. This section describes the m option.
The Jar tool automatically puts a default manifest with the pathname META-INF/MANIFEST.MF into any JAR file you create. You can enable special JAR file functionality, such as package sealing, by modifying the default manifest. Typically, modifying the default manifest involves adding special-purpose headers to the manifest that allow the JAR file to perform a particular desired function.
Warning : The text file from which you are creating the manifest must end with a new line or carriage return. The last line will not be parsed properly if it does not end with a new line or carriage return.
The basic command has this format:
jar cfm jar-file manifest-addition input-file(s)
Let’s look at the options and arguments used in this command:
- The c option indicates that you want to create a JAR file.
- The m option indicates that you want to merge information from an existing file into the manifest file of the JAR file you’re creating.
- The f option indicates that you want the output to go to a file (the JAR file you’re creating) rather than to standard output.
- manifest-addition is the name (or path and name) of the existing text file whose contents you want to add to the contents of JAR file’s manifest.
- jar-file is the name that you want the resulting JAR file to have.
- The input-file(s) argument is a space-separated list of one or more files that you want to be placed in your JAR file.
The m and f options must be in the same order as the corresponding arguments.
Note : The contents of the manifest must be encoded in UTF8.
Setting an Application’s Entry Point
If you have an application bundled in a JAR file, you need some way to indicate which class within the JAR file is your application’s entry point. You provide this information with theMain-Classheader in the manifest, which has the general form:
The valueMain-Class: classname
classnameis the name of the class that is your application’s entry point.
Recall that the entry point is a class having a method with signature
public static void main(String[] args).
After you have set the
Main-Classheader in the manifest, you then run the JAR file using the following form of thejavacommand:
Thejava -jar JAR-name
mainmethod of the class specified in theMain-Classheader is executed.
An Example
We want to execute themainmethod in the classMyClassin the packageMyPackagewhen we run the JAR file.
We first create a text file named
Manifest.txtwith the following contents:
Main-Class: MyPackage.MyClass
We then create a JAR file named
Warning: The text file must end with a new line or carriage return. The last line will not be parsed properly if it does not end with a new line or carriage return.
MyJar.jarby entering the following command:
This creates the JAR file with a manifest with the following contents:jar cfm MyJar.jar Manifest.txt MyPackage/*.class
When you run the JAR file with the following command, theManifest-Version: 1.0
Created-By: 1.6.0 (Sun Microsystems Inc.)
Main-Class: MyPackage.MyClass
mainmethod ofMyClassexecutes:
java -jar MyJar.jar
Setting an Entry Point with the JAR Tool
The ‘e’ flag (for ‘entrypoint’), introduced in JDK 6, creates or overrides the manifest’sMain-Classattribute. It can be used while creating or updating a jar file. Use it to specify the application entry point without editing or creating the manifest file.
For example, this command createsapp.jarwhere theMain-Classattribute value in the manifest is set toMyApp:
jar cfe app.jar MyApp MyApp.class
You can directly invoke this application by running the following command:
java -jar app.jar
If the entrypoint class name is in a package it may use a ‘.’ (dot) character as the delimiter. For example, if
Main.classis in a package calledfoothe entry point can be specified in the following ways:
jar cfe Main.jar foo.Main foo/Main.class
Adding Classes to the JAR File’s Classpath
You may need to reference classes in other JAR files from within a JAR file.
For example, in a typical situation an applet is bundled in a JAR file whose manifest references a different JAR file (or several different JAR files) that serves as utilities for the purposes of that applet.
You specify classes to include in the Class-Path header field in the manifest file of an applet or application. The Class-Path header takes the following form:
By using the Class-Path header in the manifest, you can avoid having to specify a long -classpath flag when invoking Java to run the your application.Class-Path: jar1-name jar2-name directory-name/jar3-name
Note : The Class-Path header points to classes or JAR files on the local network, not JAR files within the JAR file or classes accessible over internet protocols. To load classes in JAR files within a JAR file into the class path, you must write custom code to load those classes. For example, if MyJar.jar contains another JAR file called MyUtils.jar, you cannot use the Class-Path header in MyJar.jar’s manifest to load classes in MyUtils.jar into the class path.
An Example
We want to load classes in MyUtils.jar into the class path for use in MyJar.jar. These two JAR files are in the same directory.
We first create a text file named Manifest.txt with the following contents:
Class-Path: MyUtils.jar
Warning : The text file must end with a new line or carriage return. The last line will not be parsed properly if it does not end with a new line or carriage return.
We then create a JAR file named MyJar.jar by entering the following command:
This creates the JAR file with a manifest with the following contents:jar cfm MyJar.jar Manifest.txt MyPackage/*.class
The classes in MyUtils.jar are now loaded into the class path when you run MyJar.jar.Manifest-Version: 1.0
Class-Path: MyUtils.jar
Created-By: 1.6.0 (Sun Microsystems Inc.)
Working with Manifest Files: The Basics
JAR files support a wide range of functionality, including electronic signing, version control, package sealing, and others. What gives a JAR file this versatility? The answer is the JAR file’s manifest.
The manifest is a special file that can contain information about the files packaged in a JAR file. By tailoring this “meta” information that the manifest contains, you enable the JAR file to serve a variety of purposes.
This lesson will explain the contents of the manifest file and show you how to work with it, with examples for the basic features:
Understanding the Default Manifest
When you create a JAR file, a default manifest is created automatically. This section describes the default manifest.
Modifying a Manifest File
This section shows you the basic method of modifying a manifest file. The later sections demonstrate specific modifications you may want to make.
Setting an Application’s Entry Point
This section describes how to use the Main-Class header in the manifest file to set an application’s entry point.
Adding Classes to the JAR File’s Classpath
This section describes how to use the Class-Path header in the manifest file to add classes in other JAR files to the classpath when running an applet or application.
Setting Package Version Information
This section describes how to use the package version headers in the manifest file.
Sealing Packages within a JAR File
This section describes how to seal packages within a JAR file by modifying the manifest file.
Creating a JAR File
The basic format of the command for creating a JAR file is:
The options and arguments used in this command are:jar cf jar-file input-file(s)
- The c option indicates that you want to create a JAR file.
- The f option indicates that you want the output to go to a file rather than to stdout.
- jar-file is the name that you want the resulting JAR file to have. You can use any filename for a JAR file. By convention, JAR filenames are given a .jar extension, though this is not required.
- The input-file(s) argument is a space-separated list of one or more files that you want to include in your JAR file. The input-file(s) argument can contain the wildcard * symbol. If any of the “input-files” are directories, the contents of those directories are added to the JAR archive recursively.
The c and f options can appear in either order, but there must not be any space between them.
This command will generate a compressed JAR file and place it in the current directory. The command will also generate a default manifest file for the JAR archive.
Note: The metadata in the JAR file, such as the entry names, comments, and contents of the manifest, must be encoded in UTF8.
You can add any of these additional options to the cf options of the basic command:
jar command options
Option
Description
v
Produces verbose output on stdout while the JAR file is being built. The verbose output tells you the name of each file as it’s added to the JAR file.
0 (zero)
Indicates that you don’t want the JAR file to be compressed.
M
Indicates that the default manifest file should not be produced.
m
Used to include manifest information from an existing manifest file. The format for using this option is:
See Modifying a Manifest File for more information about his option.jar cmf existing-manifest jar-file input-file(s)
Warning: The manifest must end with a new line or carriage return. The last line will not be parsed properly if it does not end with a new line or carriage return.
-C
To change directories during execution of the command. See below for an example.
Note: When you create a JAR file, the time of creation is stored in the JAR file. Therefore, even if the contents of the JAR file do not change, when you create a JAR file multiple times, the resulting files are not exactly identical. You should be aware of this when you are using JAR files in a build environment. It is recommended that you use versioning information in the manifest file, rather than creation time, to control versions of a JAR file. See the Setting Package Version Information section.
An Example
Let us look at an example. A simple TicTacToe applet. You can see the source code of this Applet at TicTacToe.java. This demo contains a bytecode class file, audio files, and images having this structure:
TicTacToe folder Hierarchy
The audio and images subdirectories contain sound files and GIF images used by the applet.
You can obtain all these files from jar/examples directory when you download the entire Tutorial online. To package this demo into a single JAR file named TicTacToe.jar, you would run this command from inside the TicTacToe directory:
The audio and images arguments represent directories, so the Jar tool will recursively place them and their contents in the JAR file. The generated JAR file TicTacToe.jar will be placed in the current directory. Because the command used the v option for verbose output, you would see something similar to this output when you run the command:jar cvf TicTacToe.jar TicTacToe.class audio images
adding: TicTacToe.class (in=3825) (out=2222) (deflated 41%)
adding: audio/ (in=0) (out=0) (stored 0%)
adding: audio/beep.au (in=4032) (out=3572) (deflated 11%)
adding: audio/ding.au (in=2566) (out=2055) (deflated 19%)
adding: audio/return.au (in=6558) (out=4401) (deflated 32%)
adding: audio/yahoo1.au (in=7834) (out=6985) (deflated 10%)
adding: audio/yahoo2.au (in=7463) (out=4607) (deflated 38%)
adding: images/ (in=0) (out=0) (stored 0%)
adding: images/cross.gif (in=157) (out=160) (deflated -1%)
adding: images/not.gif (in=158) (out=161) (deflated -1%)
You can see from this output that the JAR file TicTacToe.jar is compressed. The Jar tool compresses files by default. You can turn off the compression feature by using the 0 (zero) option, so that the command would look like:
jar cvf0 TicTacToe.jar TicTacToe.class audio images
You might want to avoid compression, for example, to increase the speed with which a JAR file could be loaded by a browser. Uncompressed JAR files can generally be loaded more quickly than compressed files because the need to decompress the files during loading is eliminated. However, there is a tradeoff in that download time over a network may be longer for larger, uncompressed files.
The Jar tool will accept arguments that use the wildcard * symbol. As long as there weren’t any unwanted files in the TicTacToe directory, you could have used this alternative command to construct the JAR file:
jar cvf TicTacToe.jar *
Though the verbose output doesn’t indicate it, the Jar tool automatically adds a manifest file to the JAR archive with path name META-INF/MANIFEST.MF. See the Working with Manifest Files: The Basics section for information about manifest files.
In the above example, the files in the archive retained their relative path names and directory structure. The Jar tool provides the -C option that you can use to create a JAR file in which the relative paths of the archived files are not preserved. It’s modeled after TAR’s -C option.
As an example, suppose you wanted to put audio files and gif images used by the TicTacToe demo into a JAR file, and that you wanted all the files to be on the top level, with no directory hierarchy. You could accomplish that by issuing this command from the parent directory of the images and audio directories:
The -C images part of this command directs the Jar tool to go to the images directory, and the . following -C images directs the Jar tool to archive all the contents of that directory. The -C audio . part of the command then does the same with the audio directory. The resulting JAR file would have this table of contents:jar cf ImageAudio.jar -C images . -C audio .
By contrast, suppose that you used a command that did not employ the -C option:META-INF/MANIFEST.MF
cross.gif
not.gif
beep.au
ding.au
return.au
yahoo1.au
yahoo2.au
The resulting JAR file would have this table of contents:jar cf ImageAudio.jar images audio
META-INF/MANIFEST.MF
images/cross.gif
images/not.gif
audio/beep.au
audio/ding.au
audio/return.au
audio/yahoo1.au
audio/yahoo2.au
Viewing the Contents of a JAR File
The basic format of the command for viewing the contents of a JAR file is:
Let’s look at the options and argument used in this command:jar tf jar-file
- The t option indicates that you want to view the table of contents of the JAR file.
- The f option indicates that the JAR file whose contents are to be viewed is specified on the command line.
- The jar-file argument is the path and name of the JAR file whose contents you want to view.
The t and f options can appear in either order, but there must not be any space between them.
This command will display the JAR file’s table of contents to stdout.
You can optionally add the verbose option, v, to produce additional information about file sizes and last-modified dates in the output.
An Example
Let’s use the Jar tool to list the contents of the TicTacToe.jar file we created in the previous section:
jar tf TicTacToe.jar
This command displays the contents of the JAR file to stdout:
META-INF/MANIFEST.MF
TicTacToe.class
audio/
audio/beep.au
audio/ding.au
audio/return.au
audio/yahoo1.au
audio/yahoo2.au
images/
images/cross.gif
images/not.gif
The JAR file contains the TicTacToe class file and the audio and images directory, as expected. The output also shows that JAR file contains a default manifest file, META-INF/MANIFEST.MF, which was automatically placed in the archive by the JAR tool. For more information, see the Understanding the Default Manifest section.
All pathnames are displayed with forward slashes, regardless of the platform or operating system you’re using. Paths in JAR files are always relative; you’ll never see a path beginning with C:, for example.
The JAR tool will display additional information if you use the v option:
jar tvf TicTacToe.jar
For example, the verbose output for the TicTacToe JAR file would look similar to this:
256 Mon Apr 18 10:50:28 PDT 2005 META-INF/MANIFEST.MF
3885 Mon Apr 18 10:49:50 PDT 2005 TicTacToe.class
0 Wed Apr 20 16:39:32 PDT 2005 audio/
4032 Wed Apr 20 16:39:32 PDT 2005 audio/beep.au
2566 Wed Apr 20 16:39:32 PDT 2005 audio/ding.au
6558 Wed Apr 20 16:39:32 PDT 2005 audio/return.au
7834 Wed Apr 20 16:39:32 PDT 2005 audio/yahoo1.au
7463 Wed Apr 20 16:39:32 PDT 2005 audio/yahoo2.au
0 Wed Apr 20 16:39:44 PDT 2005 images/
157 Wed Apr 20 16:39:44 PDT 2005 images/cross.gif
158 Wed Apr 20 16:39:44 PDT 2005 images/not.gif
