JAR Files
Java Archive (JAR) files are Java‘s suitcases. They are the standard and portable way to pack up all the parts of your Java application into a compact bundle for distribution or installation.
You can put whatever you want into a JAR file:
- Java class files,
- Serialized objects,
- Data files,
- Images,
- Sounds, etc.
A JAR file can carry one or more digital signatures attesting to its integrity and authenticity. A signature can be attached to the file as a whole or to individual items.
The Java runtime system understands JAR files and can load class files directly from an archive. Pack your application’s classes in a JAR file and place them in your CLASSPATH.
You can do the applet equivalent by listing the JAR file in the ARCHIVE attribute of the HTML <applet> tag. Nonclass files (data, images, etc.) in your JAR file can also be retrieved from the classpath using the geTResource( ) method. Using this structure, your code doesn’t have to know whether any resource is in a plain file or a member of a JAR archive.
Java’s class loader can refer to any data or class file in a standard way and place it wherever it chooses; this includes items in JAR files, individual files on the classpath, and even applets on distant servers.
File Compression
Items stored in JAR files are compressed using the standard ZIP file compression. Compression makes downloading classes over a network much faster.
A quick survey of the standard Java distribution shows that a typical class file shrinks by about 40 percent when compressed.
Text files such as arbitrary HTML or ASCII containing English words often compress to one-quarter of their original size. (Conversely, image files don’t get much smaller when compressed; most common image formats have compression built in.)
Compression is not the only advantage that a JAR file has for transporting files over a network. Placing all the classes in a single JAR file enables them to be downloaded in a single transaction.
Eliminating the overhead of making HTTP requests is likely to result in significant savings since individual class files tend to be minor, and a complex applet could quickly require many of them.
On the downside, downloading a large JAR file over a slow connection before the applet can start could increase startup time.
The jar Utility:
The JDK’s jar utility is a straightforward tool for producing and reading JAR files. However, its user interface isn’t very intuitive.
It imitates the tar (tape archive) tool in Unix. You will know the following incantations if you are familiar with tar:
jar -cvf jarFile path [ path ] [ ... ]
Create jarFile containing path(s).
jar -tvf jarFile [ path ] [ ... ]
List the contents of jarFile, optionally showing just path(s).
jar -xvf jarFile [ path ] [ ... ]
Extract the contents of jarFile, optionally extracting just path(s).
The letters c, t, and x in these commands indicate to Jar whether it is extracting files from an archive, creating an archive, or listing the contents of an archive.
The f indicates that the name of the JAR file to work with is the following input. When presenting information about files, the v instructs Jar to be verbose. File sizes, modification times, and compression ratios are displayed verbosely.
The command line items that aren’t the jar’s instructions or the file it should operate on are used to name archive items.
If you create an archive, it adds the files and directories you provide. If you are extracting, only the filenames you specify will be removed from the archive. (Jar extracts all of the archive’s contents if you don’t specify any files.)
JAR Manifests
The jar command automatically adds a directory named META-INF to our archive. Files describing the JAR file’s contents are stored in the META-INF directory.
At least one file, MANIFEST.MF, is always present. The MANIFEST. MF file contains a “packing list” that names the files in the archive and a user-defined set of attributes for each entry.
A collection of lines with the form keyword: value makes up the manifest, a text file. The manifest is by default empty in Java 1.2 and later, and it just includes the version information of the JAR file:
Manifest-Version: 1.0
Created-By: 1.2.1 (Sun Microsystems Inc.)
Making a JAR file runnable
Aside from attributes, you can put a few unique values in the manifest file. One of these, Main-Class, allows you to specify the class containing the primary main( ) method for an application included in the JAR:
Main-Class: com.oreilly.Game
If you add this to your JAR file manifest (using the m option described earlier), you can run the application directly from the JAR:
% java -jar spaceblaster.jar
More importantly, you can simply click on the JAR file to launch the application under Mac OS X, Windows, and other GUI environments. The interpreter looks for the Main-Class value in the manifest and then loads the named class as the application’s initial class.
Java Virtual Machine
Java is a language that can be interpreted or compiled. Like regular microprocessor machine code, Java source code is converted into straightforward binary instructions. However, Java source is turned into universal instructions in a virtual machine, while C or C++ is reduced to native instructions for a specific processor model.
Compile Java bytecode and run it using a Java runtime interpreter. The runtime system operates in a secure virtual environment and performs all of the typical tasks of an actual processor.
Like an operating system, it maintains memory and carries out a set of stack-based instructions. It loads and calls recently referenced code blocks and generates and modifies primitive data types.
Most remarkably, it accomplishes all of this through an open specification that is well-specified and accessible to anybody who wants to create a virtual machine compatible with Java. The definition of a virtual machine and language, taken together, provides complete requirements.
No features of the base Java language are left undefined or implementation-dependent. For example, Java specifies the sizes and mathematical properties of all its primitive data types rather than leaving them up to the platform implementation.
The Java interpreter can be implemented in any preferred way for a given platform; it is compact and reasonably light.
The interpreter may be run as a separate application or embedded in another piece of software, such as a web browser. Put together, this means that Java code is implicitly portable. The same Java application bytecode can run on any platform with a Java runtime environment.
The class is the fundamental building block of Java code. Like in object-oriented languages, classes are application components that store executable code and data.
Computed Java classes are distributed in a universal binary format, including Java bytecode and additional class information. Classes can be kept separate and stored in files or archives on a network server or locally. When a program requires them, they are dynamically loaded and located at runtime.
Java features several core classes with architecture-dependent methods in addition to the platform-specific runtime system. These native methods connect the Java virtual computer to the outside world.
Classes offer low-level access to resources like the network, windowing system, and host file system and are implemented in a native language built on the host platform.
However, most of Java is written in Java itself, bootstrapped from these basic primitives, and is, therefore, portable. This includes fundamental Java tools such as the Java compiler, web browser components, and sophisticated GUI libraries, which are also written in Java and are, therefore, available on all Java platforms in precisely the same way without porting.
Interpreters have been considered slow, but Java is not a traditional interpreted language.
In addition to compiling source code down to portable bytecode, Java has also been carefully designed so that software implementations of the runtime system can further optimize their performance by compiling bytecode to native machine code on the fly. This is called just-in-time (JIT) or dynamic compilation. With JIT compilation, Java code can execute as fast as native code and maintain its transportability and security.
Compiled Java code suffers only one intrinsic performance penalty at runtime for security and virtual machine design array bounds checking. Everything else can be optimized to native code just as it can with a statically compiled language.
The Java language includes more structural information than many other languages, providing more room for optimizations. Also, remember that these optimizations can be made at runtime, considering the actual application behavior and characteristics.
JVM
A Java virtual machine (JVM) is software that implements the Java runtime system and executes Java applications. It can be a component of a more significant application, like a browser, or a standalone program, like the Java program that comes with the JDK.
The interpreter itself is typically a native application provided for every platform that bootstraps additional Java-based utilities. Tools like Java compilers and IDEs are frequently developed natively in Java to increase their portability and extensibility. For instance, NetBeans is a Java-only program.
The Java virtual machine performs all of Java’s runtime operations. It runs the compiled bytecode, loads Java class files, and checks classes from unreliable sources. It also controls system resources and memory.
The interpreter also acts as a customized compiler that converts Java bytecode into native machine instructions in implementations that support dynamic compilation.
 A Java virtual machine (VM) runs both types of Java programs. A standalone Java application is full-featured software designed to run independently.Â