The Java Archive (JAR) file format bundles multiple files into a single archive file. The file format is based on ZIP and the ZLIB compression format, so the Java jar tool can be used as a (command line) replacement for pkzip that works on Unix platforms. Typically a JAR file will contain the class files and auxiliary resources associated with applets and applications -- not just class files.
Why?
Jar files can be elements on a class path:
java -cp dir/dir1:lib1.jar:dir/dir2:lib2.jar:. Application
Operation | Command |
---|---|
Creating a JAR file | jar cf jar-file input-file(s) |
Viewing the contents of a JAR file | jar tf jar-file |
Extracting the contents of a JAR file | jar xf jar-file |
Extracting specific files from a JAR file | jar xf jar-file archived-file(s) |
Merging manifest information | jar cmf manifest-addition jar-file input-file(s) |
Updating existing jar | jar uf jar-file input-file(s) |
Creating a JAR file (Java 1.6) | jar cef entry jar-file input-file(s) |
To run an application packaged as a JAR file
(version 1.2 -- requires Main-Class manifest header) |
java -jar app.jar |
To invoke an applet packaged as a JAR file |
<applet code=AppletClassName.class
archive="JarFileName.jar" width=width height=height> </applet> |
Manifest entries:
main | Main-Class: Main Main-Class: pack.ClassName |
class path | Class-Path: http://www.univ.edu/file.jar Class-Path: file:/directory/subdirectory/ Class-Path: file:/directory/subdirectory/file.jar Class-Path: file1.jar file2.jar |
The -jar flag tells the interpreter that the application is packaged in the JAR file format.java -jar jar-file
Before this command will work, however, the runtime environment needs to know which class within the JAR file is the application's entry point.
To indicate which class is the application's entry point, you must add a Main-Class header to the JAR file's manifest. The header takes the form:
The header's value, classname, is the name of the class that's the application's entry point.Main-Class: classname
javac Main.java echo "Main-Class: Main" >! mc.mf # create a manifest file entry jar -cvmf mc.mf main.jar Main.class added manifest adding: Main.class(in = 414) (out= 284)(deflated 31%) rm mc.mf # file no longer needed java -jar main.jar # jar file now executes without mentioning main
Applet in jar file:
<applet code=TicTacToe.class archive="TicTacToe.jar" width=120 height=120> </applet>
jar:<url>!/{entry}for example:
jar:http://www.foo.com/bar/baz.jar!/COM/foo/Quux.class jar:file:/export/home/faculty/stansif/public_html/java/applets/image/view.jar!/image.gif
final java.net.URL url = X.class.getResource ("/dir/image.png"); final ImageIcon icon = new ImageIcon (url);
A package can be sealed by adding the Sealed header beneath the header naming the package that's to be sealed.:
Name: myCompany/myPackage/ Sealed: true
The default manifest created by the Jar tool does not contain any Sealed headers, of course, because packages are not sealed by default. To seal a package, you therefore have to add the Sealed header yourself. To insert the Sealed header in a JAR file's manifest, you first need to write a text file containing the appropriate headers. The file you write doesn't have to be a complete manifest file; it can contain just enough information for the Jar tool to know where and what information to merge into the default manifest.
java.lang.Package (Java API documentation) (local copy)
class Main { public static void main(String[] args) { Package[] pkgs = Package.getPackages(); for (int i=0; i<pkgs.length; i++) { System.out.println(pkgs[i].getName()); System.out.println(" Specification Title: " + pkgs[i].getSpecificationTitle()); System.out.println(" Specification Version: " + pkgs[i].getSpecificationVersion()); System.out.println(" Specification Vendor: " + pkgs[i].getSpecificationVendor()); System.out.println(" Implementation Title: " + pkgs[i].getImplementationTitle()); System.out.println(" Implementation Version: " + pkgs[i].getImplementationVersion()); System.out.println(" Implementation Vendor: " + pkgs[i].getImplementationVendor()); if (pkgs[i].isSealed()) { System.out.println(" Sealed: true"); } } } }