The Java platform
The Java platform is the name given to the computing platform from Oracle that helps users to run and develop Java applications. The platform does not just enable a user to run and develop a Java application, but also features a wide variety of tools that can help developers work efficiently with the Java programming language.
The platform consists of two essential pieces of software:
- the Java Runtime Environment (JRE), which is needed to run Java applications and applets; and,
- the Java Development Kit (JDK), which is needed to develop those Java applications and applets. If you have installed the JDK, you should know that it comes equipped with a JRE as well. So, for all the purposes of this book, you would only require the JDK.
In this section, we will explore in further detail what these two software components of the Java platform do.
Java Runtime Environment (JRE)Edit
Any piece of code written in the Java programming language can be run on any operating system, platform or architecture — in fact, it can be run on any device that supports the Java platform. Before Java, this amount of ubiquity was very hard to achieve. If a software was written for a Unix-based system, it was impossible to run the same application on a Windows system — in this case, the application was native only to Unix-based systems.
A major milestone in the development of the Java programming language was to develop a special runtime environment that would execute any Java application independent of the computer's operating system, platform or architecture.
The Java Runtime Environment (JRE) sits on top of the machine's operating system, platform and architecture. If and when a Java application is run, the JRE acts as a liaison between the underlying platform and that application. It interprets the Java application to run in accordance with the underlying platform, such that upon running the application, it looks and behaves like a native application. The part of the JRE that accomplishes this complex liaison agreement is called the Java Virtual Machine (JVM).
Figure 1: Java applications can be written once and run anywhere. This feature of the Java platform
is commonly abbreviated to WORA in formal Java texts.
Executing native Java code (or byte-code)Edit
Native Java applications are preserved in a special format called the byte-code. Byte-code remains the same, no matter what hardware architecture, operating system, or software platform it is running under. On a file-system, Java byte-code resides in files that have the
.class (also known as a class file) or the
.jar (also known as a Java archive) extension. To run byte-code, the JRE comes with a special tool (appropriately named java).
Suppose your byte-code is called
SomeApplication.class. If you want to execute this Java byte-code, you would need to use the following command in Command Prompt (on Windows) or Terminal (on Linux or Mac OS):
$ java SomeApplication
If you want to execute a Java byte-code with a
.jar extension (say,
SomeApplication.jar), you would need to use the following command in Command Prompt (on Windows) or Terminal (on Linux or Mac OS):
|Execution with a jar
$ java -jar SomeApplication.jar
|Not all Java class files or Java archives are executable. Therefore, the java tool would only be able to execute files that are executable. Non-executable class files and Java archives are simply called class libraries.|
Do you have a JRE?Edit
Most computers come with a pre-installed copy of the JRE. If your computer doesn't have a JRE, then the above commands would not work. You can always check what version of the JRE is installed on the computer by writing the following command in Command Prompt (on Windows) or Terminal (on Linux or Mac OS):
$ java -version
Java Virtual Machine (JVM)Edit
Quite possibly, the most important part of the JRE is the Java Virtual Machine (JVM). The JVM acts like a virtual processor, enabling Java applications to be run on the local system. Its main purpose is to interpret (read translate) the received byte-code and make it appear as native code. The older Java architecture used this process of interpretation to execute Java byte-code. Even though the process of interpretation brought the WORA principle to diverse machines, it had a drawback — it consumed a lot of time and clocked the system processor intensively to load an application.
Figure 2: A JVM interpreter translates the byte-code line-by-line to make it appear as if a native application is being executed.
Since version 1.2, the JRE features a more robust JVM. Instead of interpreting byte-code, it down-right converts the code straight into equivalent native code for the local system. This process of conversion is called just-in-time compilation or JIT-compilation. This process only occurs when the byte-code is executed for the first time. Unless the byte-code itself is changed, the JVM uses the compiled version of the byte-code on every successive execution. Doing so saves a lot of time and processor effort, allowing applications to execute much faster at the cost of a small delay on first execution.
Figure 3: A just-in-time compiler only compiles the byte-code to equivalent native code at first execution. Upon every successive
execution, the JVM merely uses the already compiled native code to optimize performance.
The JVM is an intelligent virtual processor. It has the ability to identify areas within the Java code itself that can be optimized for faster and better performance. Based on every successive run of your Java applications, the JVM would optimize it to run even better.
|There are portions of Java code that do not require it to be JIT-compiled at runtime, e.g., the Reflection API; therefore, code that uses such functions are not necessarily fully compiled to native code.|
Was JVM the first virtual machine?Edit
Java was not the first virtual-machine-based platform, though it is by far the most successful and well-known. Previous uses for virtual machine technology primarily involved emulators to aid development for not-yet-developed hardware or operating systems, but the JVM was designed to be implemented entirely in software, while making it easy to efficiently port an implementation to hardware of all kinds.
Java Development Kit (JDK)Edit
The JRE takes care of running the Java code on multiple platforms, however as developers, we are interested in writing pure code in Java which can then be converted into Java byte-code for mass deployment. As developers, we do not need to write Java byte-code; rather we write the code in the Java programming language (which is quite similar to writing C or C++ code).
Upon downloading the JDK, a developer ensures that their system has the appropriate JRE and additional tools to help with the development of applications in the Java programming language. Java code can be found in files with the extension .java. These files are called Java source files. In order to convert the Java code in these source files to Java byte-code, you need to use the Java compiler tool installed with your JDK.
The Java compilerEdit
The Java compiler tool (named javac in the JDK) is the most important utility found with the JDK. In order to compile a Java source file (say,
SomeApplication.java) to its respective Java byte-code, you would need to use the following command in Command Prompt (on Windows) or Terminal (on Linux or Mac OS):
This command would convert the
SomeApplication.java source file into its equivalent Java byte-code. The resultant byte-code would exist in a newly created file named
SomeApplication.class. This process of converting Java source files into their equivalent byte-codes is known as compilation.
Figure 4: The basic Java compilation process
There are a huge array of tools available with the JDK that will all be explained in due time as you progress with the book. These tools are briefly listed below in order of their usage:
appletviewer— Java applets require a particular environment to execute. Typically, this environment is provided by a browser with a Java plug-in, and a web server serving the applet. However, during development and testing of an applet it might be more convenient to start an applet without the need to fiddle with a browser and a web server. In such a case, Oracle's appletviewer from the JDK can be used to run an applet.
- For more about annotation processing, read this
In Java 1.5 (alias Java 5.0) Oracle added a mechanism called annotations. Annotations allow the addition of meta-data to Java source code, and even provide mechanisms to carry that meta-data into compiled
apt— An annotation processing tool which digs through source code, finds annotation statements in the source code and executes actions if it finds known annotations. The most common task is to generate some particular source code. The actions apt performs when finding annotations in the source code are not hard-coded into apt. Instead, one has to code particular annotation handlers (in Java). These handlers are called annotation processors. It can also be described in a simple way without the Oracle terminology: apt can be seen as a source code preprocessor framework, and annotation processors are typically code generators.
Integration of non-Java and Java codeEdit
javah— A Java class can call native, or non-Java, code that has been prepared to be called from Java. The details and procedures are specified in the JNI (Java Native Interface). Commonly, native code is written in C (or C++). The JDK tool javah helps to write the necessary C code, by generating C header files and C stub code.
Class library conflictsEdit
extcheck— It can be used prior to the installation of a Java extension into the JDK or JRE environment. It checks if a particular Jar file conflicts with an already installed extension. This tool appeared first with Java 1.5.
Software security and cryptography toolsEdit
The JDK comes with a large number of tools related to the security features of Java. Usage of these tools first requires study of the particular security mechanisms. The tools are:
keytool— To manage keys and certificates
jarsigner— To generate and verify digital signatures of JARs (Java ARchives)
policytool— To edit policy files
kinit— To obtain Kerberos v5 tickets
klist— To manage Kerberos credential cache and key table
ktab— To manage entries in a key table
The Java archiverEdit
jar— (short for Java archiver) is a tool for creating Java archives or jar files — a file with
.jaras the extension. A Java archive is a collection of compiled Java classes and other resources which those classes may require (such as text files, configuration files, images) at runtime. Internally, a jar file is really a .zip file.
The Java debuggerEdit
jdb— (short for Java debugger) is a command-line console that provides a debugging environment for Java programs. Although you can use this command line console, IDE's normally provide easier to use debugging environments.
Documenting code with JavaEdit
As programs grow large and complex, programmers need ways to track changes and to understand the code better at each step of its evolution. For decades, programmers have been employing the use of special programming constructs called comments — regions that help declare user definitions for a code snippet within the source code. But comments are prone to be verbose and incomprehensible, let alone be difficult to read in applications having hundreds of lines of code.
javadoc— Java provides the user with a way to easily publish documentation about the code using a special commenting system and the javadoc tool. The javadoc tool generates documentation about the Application Programming Interface (API) of a set of user-created Java classes. javadoc reads source file comments from the
.javasource files and generates HTML documents that are easier to read and understand without looking at the code itself.
javap— Where Javadoc provide a detailed view into the API and documentation of a Java class, the javap tool prints information regarding members (constructors, methods and variables) in a class. In other words, it lists the class' API and/or the compiled instructions of the class. javap is a formatting disassembler for Java bytecode.
The native2ascii toolEdit
native2ascii is an important, though underappreciated, tool for writing properties files — files containing configuration data — or resource bundles — files containing language translations of text.
Such files can contain only ASCII and Latin-1 characters, but international programmers need a full range of character sets. Text using these characters can appear in properties files and resource bundles only if the non-ASCII and non-Latin-^1 characters are converted into Unicode escape sequences (\uXXXX notation).
The task of writing such escape sequences is handled by
native2ascii. You can write the international text in an editor using the appropriate character encoding, then use
native2ascii to generate the necessary ASCII text with embedded Unicode escape sequences. Despite the name,
native2ascii can also convert from ASCII to native, so it is useful for converting an existing properties file or resource bundle back to some other encoding.
native2ascii makes most sense when integrated into a build system to automate the conversion.
Remote Method Invocation (RMI) toolsEdit
Java IDL and RMI-IIOP ToolsEdit
Deployment & Web Start ToolsEdit
Browser Plug-In ToolsEdit
Monitoring and Management Tools / Troubleshooting ToolsEdit
With Java 1.5 a set of monitoring and management tools have been added to the JDK, in addition to a set of troubleshooting tools.
The monitoring and management tools are intended for monitoring and managing the virtual machine and the execution environment. They allow, for example, monitoring memory usage during the execution of a Java program.
The troubleshooting tools provide rather esoteric insight into aspects of the virtual machine. (Interestingly, the Java debugger is not categorized as a troubleshooting tool.)
All the monitoring and management and troubleshooting tools are currently marked as "experimental" (which does not affect jdb). So they might disappear in future JDKs.
Java class libraries (JCL)Edit
In most modern operating systems, a large body of reusable code is provided to simplify the programmer's job. This code is typically provided as a set of dynamically loadable libraries that applications can call at runtime. Because the Java platform is not dependent on any specific operating system, applications cannot rely on any of the existing libraries. Instead, the Java platform provides a comprehensive set of standard class libraries, containing much of the same reusable functions commonly found in modern operating systems.
The Java class libraries serve three purposes within the Java platform. Like other standard code libraries, they provide the programmer with a well-known set of functions to perform common tasks, such as maintaining lists of items or performing complex string parsing. In addition, the class libraries provide an abstract interface to tasks that would normally depend heavily on the hardware and operating system. Tasks such as network access and file access are often heavily dependent on the native capabilities of the platform. The Java java.net and java.io libraries implement the required native code internally, then provide a standard interface for the Java applications to perform those tasks. Finally, some underlying platforms may not support all of the features a Java application expects. In these cases, the class libraries can either emulate those features using whatever is available, or provide a consistent way to check for the presence of a specific feature.
The success of the Java platform and the concepts of the write once, run anywhere principle has led to the development of similar frameworks and platforms. Most notable of these is the Microsoft's .NET framework and its open-source equivalent Mono.
The .NET frameworkEdit
The .NET framework borrows many of the concepts and innovations of Java — their alternative for the JVM is called the Common Language Runtime (CLR), while their alternative for the byte-code is the Common Intermediate Language (CIL). In fact, the .NET platform had an implementation of a Java-like language called Visual J# (formerly known as J++).
J# is normally not supported with the JVM because instead of compiling it in Java byte-code, the .NET platform compiles the code into CIL, thus making J# different from the Java programming language. Furthermore, because J# implements the .NET Base Class Libraries (BCL) instead of the Java Class Libraries, J# is nothing more than a non-standard extension of the Java programming language. Due to the lack of interest from developers, Microsoft had to withdraw their support for J#, and focused on a similar programming language: C#.
Third-party compilers targeting the JVMEdit
The word Java, by itself, usually refers to the Java programming language which was designed for use with the Java platform. Programming languages are typically outside of the scope of the phrase "platform". However, Oracle does not encourage the use of any other languages with the platform, and lists the Java programming language as a core part of the Java 2 platform. The language and runtime are therefore commonly considered a single unit.
There are cases where you might want to program using a different language (say, Python) and yet be able to generate Java byte-code (instead of the Python compiled code) to be run with the JVM. Many third-party programming language vendors provide compilers that can compile code written in their language to Java byte-code. For instance, Python developers can use Jython compilers to compile Python code to the Java byte-code format (as illustrated below).
Figure 5: Third-party JVM-targeted compilation for non-Java source compilation to Java byte-code. Illustrated example
shows Python source being compiled to both Python compiled code and Java byte-code.
Of late, JVM-targeted third-party programming and scripting languages have seen tremendous growth. Some of these languages are also used to extend the functionalities of the Java language itself. A few examples include the following: