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 softwares:
- 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)
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).
Executing native Java code (or byte-code)
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?
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)
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.
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.
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?
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)
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 compiler
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.
Java class libraries (JCL)
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 framework
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 JVM
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).
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: