Understanding Java Distributions
In this chapter, we will examine how the Java language came about and how it is managed. While the word Java is used throughout this book, please note that I am referring to the Java Standard Edition or Java SE. There are numerous versions and distributions of Java, and this sometimes leads to confusion over which one to use. Is Java free, or do I have to license it? Can I include a Java runtime with my software? Can I distribute my own version of Java? These and other questions will be answered in this chapter.
You will learn how to install Java on Linux, macOS, and Windows. The significant tools that are part of the Java installation are highlighted in this chapter and will be used in later chapters.
- A little history
- What makes Java special?
- Why are there many distributions of Java?
- Which Java should you get?
- How is Java licensed?
- Why are there so many versions of Java?
- Installing Java
- What’s in the box?
Let’s begin with a quick history lesson.
To code in Java or run Java programs on your desktop, you need a computer and operating system that supports the Java Development Kit (JDK). There are JDKs available for different operating systems and different central processing units (CPUs). If you are running the Windows operating system, your only concern is whether you are running 32-bit or 64-bit. On macOS, there are versions of Java for both Intel and Apple (ARM) CPUs. If your operating system is Linux, there are more variations depending on your computer’s hardware. There is even a version of Java for IBM mainframes that run Linux.
The only other hardware requirement is the amount of RAM on your system. I have run Java applications on a Raspberry Pi 3 Model B with just 1 GB of RAM. As a developer, you are doing more than just running programs. You run editors, compilers, web servers, database servers, and your usual software. Doing this needs memory. I recommend a minimum of 8 GB for a development system; 16 GB is ideal, and 32 GB might let you play games while you code.
A little history
Java did not start as a language called Java. In the early 1990s, the company Sun Microsystems, known for its SPARC workstations and the Solaris operating system, saw potential in the consumer electronics space. They put together a team of engineers to develop products in this space under the title Green Project. Their first device was called the Star7, a small handheld computer that used a custom version of Solaris. The Star7 is the first personal digital assistant, preceding the Apple Newton by a year. As part of the development of Star7, a language was created. James Gosling, a Canadian software engineer working for Sun, led a team that developed this new language for the Star7, called Oak. The Star7 never went into production, but Oak was destined to take over the world.
One of the consumer electronics targets Sun hoped that the Star7 could be used for was set-top boxes for the cable TV industry. They set up a company called FirstPerson and made a bid to develop a set-top box for the cable provider Time Warner. They lost the bid. While they were unsuccessful in bringing the Star7 to market, they saw potential in the Oak language. The only problem was that Oak was already trademarked.
There are numerous stories about how Oak became Java. Was it named after their favorite beverage or an island in Indonesia? Java was just 1 of 12 possible names. The names were turned over to the legal department for trademark searches. Of the names on the list given to the legal team, Java was the fourth name on the list and the first to pass the legal review. Java became the new name for Oak.
The early 1990s was also the time that the World Wide Web (WWW) became available to anyone with an internet connection. The Green team developed a browser called WebRunner coded with Java as a showcase for the language. This browser could run programs called Applets, which were written in Java. Java 1.0 was introduced to the world in 1995, and WebRunner was renamed HotJava. Netscape also licensed Java for their Navigator browser.
In 1998 Java 1.2, also referred to as Java 2, was introduced. Among many new features was the Swing GUI library, which significantly improved writing desktop GUI programs that ran independently from a browser. The Java EE platform was released in 1999 as J2EE. It was used to develop Java web servers. Now, you could write Java programs that responded to requests from a browser and were run on a web server. The rest, as the expression goes, is history.
What makes Java special?
Java was designed by Gosling and his team to address shortcomings they perceived in C++. The most significant of the shortcomings was memory management. In C++, variables of type pointer were used to allocate memory for objects. Once an object was no longer needed, the developer’s responsibility was to release or deallocate the memory. Forgetting to do so resulted in memory leaks. A leak is a block of memory marked as in use but no longer accessible by a pointer. While Java still required you to allocate memory, you did not need to deallocate it. A process called the garbage collector tracked all memory allocations. When a pointer, named a reference in Java, went out of scope, the garbage collector would release its memory automatically. There are five garbage collectors available. The Parallel Garbage Collector is the default general-purpose collector. Serial Garbage Collector, CMS Garbage Collector, G1 Garbage Collector, and Z Garbage Collector use algorithms for specific types of applications such as those requiring low latency or requiring only a single thread.
However, garbage collection is not the most significant feature of Java. What sets Java apart from its predecessors, C and C++, is that Java programs do not execute directly in the computer’s operating system. Instead, compiled Java programs, called bytecode, execute inside another process called the Java virtual machine (JVM).
The JVM is a software simulation of a computer. The bytecode is the machine language of this simulated machine. The JVM then translates the bytecode into the machine language of the underlying computer.
The JVM is responsible for optimizing the code and performing garbage collection.
Native languages such as C and C++ are directly compiled into the machine language of the CPU coupled with the computer’s operating system it will run on. Any libraries used must also have been compiled for a specific CPU and operating system. This means that a program compiled for an Intel CPU running Windows or an Apple M1 CPU running a specific version of macOS must be recompiled for an Intel CPU running Linux.
Java turns this concept on its head. Code that you write in Java and compile into bytecode can run on any hardware and operating system unchanged if there is a JVM for that computer. Java describes itself as a Write Once Run Anywhere language. This means that a Java application written on and for an Intel CPU will also run on an ARM-based system unchanged and without the need to recompile if there is a JVM for that platform.
Java is not the only language that runs in the JVM. More languages were developed to take advantage of the JVM while at the same time taking a different approach and syntax from Java. Here are four of the most widely used ones:
We now know what makes Java special in relation to languages that do not have a virtual machine. What can be confusing is that there is not just one version of Java distributed by just one company. Why? Let's take a look at that next.
Why are there many distributions of Java?
Java was first released as proprietary software. In 2006, Sun Microsystems created an open source version of Java called the OpenJDK with a GNU General Public License allowing developers to change and share the program. Sun (and later, the new owner, Oracle) retained Java-related intellectual property and copyrights.
One way to describe Java is to state that only JDKs and runtimes are considered Java if they pass an extensive suite of tests called the Technology Compatibility Kit (TCK). While Java was designated open source, initially, TCK was not. It needed to be licensed, for a fee, from Oracle. This resulted in very few companies making their own branded version of Java.
Today, however, it is possible to get access to the TCK without paying a fee. You have to make a formal request to Oracle, along with presenting several supporting documents explaining why you require access to the TCK. A screening committee will review your request and decide whether to grant you access to the TCK. At the time of writing, 27 organizations have signed the OpenJDK Community TCK License Agreement (OCTLA) and have access to the TCK.
So, why do companies still distribute their own branded version of Java? The simplest answer is to provide support to clients who wish to use Java in situations where the distributor may have more experience in a particular domain. Cloud providers such as Microsoft and Amazon have their own branded versions of Java that have been optimized for their cloud infrastructure. BellSoft, the distributor of the Liberica distribution, is one of the leaders involved in ARM versions of Java. While it might not make much of a difference which distribution you choose, the distribution your clients will use is significant.
Regardless of the distributor, the language is maintained by Oracle. A well-established process allows anyone to propose changes to the language. Through the Java Community Process (JCP), all changes, additions, and removals from the language are carefully reviewed.
The actual coding of changes to the JDK is primarily the responsibility of developers working for Oracle. Consider joining the JCP to keep abreast of changes and contribute to the language.
Which Java should you get?
All distributions of Java since Java 11, including Oracle’s distribution, are based on the OpenJDK source code. It should not matter whose distribution of Java you choose if it has passed the TCK. If you do not have a distribution you must use, then I recommend the Eclipse Adoptium version called Temurin. This version has passed the TCK. Java is a registered trademark, so the word cannot be used for distributions other than from Oracle, hence the name Temurin. If you are curious about where this name came from, I will give you a hint – it is an anagram.
You might think that the obvious choice for a Java distribution would be an Oracle-branded version. This was pretty much the case until the final release of Java 8. With this release, Oracle required companies that distributed Java as part of their commercial offerings to purchase a commercial support license for access to updates to Java. Starting with Java 11, Oracle required commercial licensees to purchase a subscription for every developer. Personal use of the Oracle-branded JDK has remained free to use, though.
This gets confusing because should you choose to use the OpenJDK distribution or any other distribution based on the OpenJDK except for Oracle’s, there are no fees required for commercial distribution. With the release of Java 17, Oracle changed its licensing again. Now called the Oracle No-Fee Terms and Conditions (NFTC), this now allows you to use Oracle’s Java for the development of software and then distribute this version of Java with your program without the need for a subscription or fee. This is only applicable to versions of Java starting at 17. Versions from 8 to 16 are still subject to the licenses.
How is Java licensed?
If you plan to use Java to develop software commercially, then how it is licensed is important to you. As already stated, the OpenJDK carries the GNU General Public License version 2, commonly referred to as the GPLv2. The GPL is widely used in open source software. At its most basic level, it requires any software that uses GPL licensed code to also be subject to the GPL. This means that any software you create must make its source code available under the same conditions. Copyright and intellectual property rights stay with the author of the work, either Oracle or you.
Java’s GPLv2 carries with it the Classpath Exception, also called the linking exception. A classpath, like an operating system path, is the location of classes and packages that the JVM and Java compiler will use. Under this exception, you do not need to supply the source code when you distribute your application. The software you write that is linked to Java does not require a GPLv2 license. It can remain proprietary and cannot be freely used like GPL software. You choose the licensing for the code that you generate.
Why are there so many versions of Java?
Java is constantly evolving – bug fixes, enhancements, and new features are in continuous development. Java was initially numbered as 1 plus a version number. The first nine versions starting in 1996 and until 2014 were 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, and 1.8. Between each of these versions, there was a third number that represented an update rather than a major revision, such as 1.8_202.
Starting with Java 1.8, then subsequently named Java 8, here is the timeline of Java versions:
Table 1.1 – Timeline of Java versions
You will see several versions designated LTS, short for Long Term Support, by Oracle. These versions are expected to be supported with bug fixes and security updates for at least 8 years. The non-LTS versions, also called feature releases, are accumulative fixes, updates, and preview features. Support for these versions is expected to last only until the next non-LTS or LTS version is released. Companies that have their own Java distribution may provide support for longer than Oracle does.
LTS versions are typically what many organizations prefer to use for their products. Java 8, released in March 2014, is still supported and will be until December 2030. Subsequent LTS versions are being supported for just 8 years but, as already mentioned, may be supported by other Java distributors for a longer period. The current schedule for new releases of Java has an LTS version every 2 years. A non-LTS version is released every 6 months.
If you plan to develop server-side software, you must use an LTS version. Libraries required for server-side are written to use a specific LTS version. When a new LTS version is released, it might take some time for all such libraries to be updated as is currently the case with LTS Java 17. As I write this, most server-side applications are running Java 11 and some still even use Java 8.
What has contributed to Java’s success is evident in the continuing and now regular cadence of releases. This ensures that Java continues to be a state-of-the-art language.
Installing Java is a simple process. As a developer, you will install the JDK from any of the distributors. Most Java distributors have packaged Java with an installer and as a compressed file without an installer that you can download. The choice depends on your OS, CPU, and whether you are the administrator or superuser and can use an installer. Or, you are a client and can only install the compressed file.
As an admin
As an admin, you can install Java for all users of the computer in the following ways.
Download the appropriate (32- or 64-bit)
.msi file for Java from https://adoptium.net/. This type of file contains an installer that will place Java in the folder of your choice and configure the appropriate environment variables. Just double-click on the
.msi file after it is downloaded. The Windows installer will lead you through the installation.
You have two options for installing Java for macOS. The first is to download the
.pkg file for Mac that includes an installer. Just double-click on the
.pkg file after it is downloaded. The Apple installer will lead you through the installation.
With HomeBrew installed, you can install the OpenJDK version with the following:
brew install openjdk@17
To install the Eclipse Temurin version of Java 17, use the following:
brew tap homebrew/cask-versions brew install --cask temurin17
On Linux, you use the
apt install command-line tool. You must be a superuser/admin to use this tool. You also include the distribution and version you require. You install the OpenJDK Java at the command line with the following:
sudo apt install openjdk-17-jdk
To install the Eclipse Temurin version of Java, use the following:
sudo apt install temurin-17-jdk
If it shows you the version and distribution name of Java that you just installed, you are done and ready to code Java. The version number may be different depending on when you download Java or use
apt install. Here is what you should see:
>java -version openjdk version "17.0.3" 2022-04-19 OpenJDK Runtime Environment Temurin-17.0.3+7 (build 17.0.3+7) OpenJDK 64-Bit Server VM Temurin-17.0.3+7 (build 17.0.3+7, mixed mode, sharing)
Linux and macOS
$ java -version openjdk version "17.0.3" 2022-04-19 OpenJDK Runtime Environment Temurin-17.0.3+7 (build 17.0.3+7) OpenJDK 64-Bit Server VM Temurin-17.0.3+7 (build 17.0.3+7, mixed mode, sharing)
As a non-admin
If you are not an admin, then you can still install Java but only you will be able to use it.
Linux and macOS
For Linux, use the following:
tar xzf OpenJDK17U-jdk_x64_linux_hotspot_17.0.3_7.tar.gz
For macOS, use the following:
Configuring environment variables
The first environment variable is
JAVA_HOME. Certain Java processes, such as web servers, need to know where Java is installed to be able to access specific components in the JDK. It must be assigned the full path to the folder in which you have installed Java.
The second environment variable is
PATH. When a program is run from the command line, the OS will look for an executable file in the current directory. If it is not found, then it will go through every directory in the path to look for it.
You will have to enter these commands every time you open a console. Adjust the command based on your login name and the version of Java you are installing. While you can install multiple versions of Java, only one can be used for
set JAVA_HOME= C:\devapp\jdk-17.0.2+8 set PATH=%JAVA_HOME%\bin;%PATH%
export JAVA_HOME=/home/javadev/java/jdk-17.0.2+8 export PATH=$JAVA_HOME/bin:$PATH
This assumes that you are logged in as
javadev and you are placing Java in a directory called
java. These two lines can be added to your
.profile file in your home directory so that they execute every time you log in.
export JAVA_HOME=/Users/javadev/java/jdk-17.03+7/Contents/Home export PATH=$JAVA_HOME/bin:$PATH
This assumes that you are logged in as
javadev and you are placing Java in a directory called
java. These two lines can be added to your
.bash.profile file in your home directory so that they execute every time you log in.
You can quickly determine whether your installation of Java is correct. Open a command or console window on whatever system you are using. If you performed the non-admin installation, then ensure that
PATH have been updated and set. In the command window, enter the following:
If the installation was successful, the output, if you installed the OpenJDK, will be as follows:
openjdk version "17.0.3" 2022-04-19 OpenJDK Runtime Environment (build 17.0.3+7-Ubuntu-0ubuntu0.20.04.1) OpenJDK 64-Bit Server VM (build 17.0.3+7-Ubuntu-0ubuntu0.20.04.1, mixed mode, sharing)
The output, if you installed the Temurin JDK, will be as follows:
openjdk version "17.0.3" 2022-04-19 OpenJDK Runtime Environment Temurin-17.0.3+7 (build 17.0.3+7) OpenJDK 64-Bit Server VM Temurin-17.0.3+7 (build 17.0.3+7, mixed mode, sharing)
Your installation is now complete and verified. Let's now examine some of the files that you just installed.
What is in the box?
The JDK contains the programs and libraries necessary to compile your source code into bytecode and then execute your code in the JVM program. It also includes numerous tools that support your work as a developer.
Java 9 introduced a new way to package Java applications that rendered the JRE superfluous. As of Java 11, Oracle no longer distributes a JRE for both their distribution and the OpenJDK. Certain distributions from other companies may still provide a JRE for the current versions of Java. We will look at the modular approach to packaging Java applications in a later chapter.
The installation of Java will take up approximately 300 MB of disk space depending on the underlying OS.
The following are the directory structures from a Linux and Windows Java installation. The first is for Ubuntu but will be almost identical on all Linux and macOS installations.
$ ls -g -G total 36 -rw-r--r-- 1 2439 Apr 19 17:34 NOTICE drwxr-xr-x 2 4096 Apr 19 17:34 bin drwxr-xr-x 5 4096 Apr 19 17:33 conf drwxr-xr-x 3 4096 Apr 19 17:33 include drwxr-xr-x 2 4096 Apr 19 17:33 jmods drwxr-xr-x 72 4096 Apr 19 17:33 legal drwxr-xr-x 5 4096 Apr 19 17:34 lib drwxr-xr-x 3 4096 Apr 19 17:33 man -rw-r--r-- 1 1555 Apr 19 17:34 release
>dir 2022-03-29 11:28 AM <DIR> . 2022-05-03 05:41 PM <DIR> .. 2022-03-29 11:28 AM <DIR> bin 2022-03-29 11:28 AM <DIR> conf 2022-03-29 11:28 AM <DIR> include 2022-03-29 11:28 AM <DIR> jmods 2022-03-29 11:28 AM <DIR> legal 2022-03-29 11:28 AM <DIR> lib 2022-03-29 11:28 AM 2,401 NOTICE 2022-03-29 11:28 AM 1,593 release
If we investigate the
bin folder, we will find several executable programs that Java refers to as its tools. On a Windows system, they all have the
.exe extension; on Linux and macOS, they appear as names only. In this chapter, we will discuss the following tools:
These are tools we will be using in the coming chapters. See the tool specification link in the Further reading section for details on all the tools included in the JDK.
We have divided these tools into the following categories:
- Compiling and executing a Java program
- Assembling and packaging a Java application
- Documenting Java classes
- Read, Evaluate, Print, and Loop (REPL)
Compiling and executing a Java program
java or javaw.exe
This is the tool that starts up the JVM process and then executes the bytecode file in the process. When using
java, a console window will open and remain open until the JVM process ends. The
javaw tool also starts up the JVM and executes a bytecode program. It will not open a console.
Windows users typically do not expect a console to open as they may have never seen one or interacted with one. If you wish to create a Windows shortcut to run a Java program, you will use
We will examine these three commands in Chapter 2, Code, Compile, and Execute.
Assembling and packaging a Java application
A Java program can be constructed of hundreds, thousands, or even more
.class files. In these cases, it is necessary to assemble all these files along with any supporting files (such as images) into a single file. Some of the tools that do so are the following.
A Java program or library usually consists of multiple
.class files. To simplify the delivery of such programs, the
jar tool combines all the class files of an application or library into a single file that uses ZIP compression and has the
.jar extension. A
.jar file can be designated as executable. In this case, you already have a Java JDK or JRE installed. We will see how this tool is used in Chapter 2,Code, Compile, and Execute.
jmod and jlink
Java 9 introduced the concept of modular Java, an approach to assembling Java applications that uses a new format for combining class files called
.jmod files. These files are like
.jar files in that they are ZIP compressed files. The
jmod tool creates
Until Java 9 came along, a single file called
rt.jar held all the Java libraries. Starting with Java 9, the Java libraries exist as individual
.jmod files. Java packages the JVM file as a
.jmod file. What this means to a developer is that it is possible to distribute Java applications that include the JVM and only those components of Java that must be available to execute your program. It is now unnecessary to have the JDK or JRE pre-installed as all that you need to execute the program is in the archive. You still need the
jar tool to construct such an executable as you cannot execute
.jmod files. We will see how these two tools are used in Chapter 16, Deploying Java in Standalone Packages and Containers.
jpackage tool creates native applications that hold a Java application and a Java runtime. It is used with either
.jmod files. The output is an executable file, such as
.exe for Windows, or a
.dmg file for a macOS system. We will see how this tool is used in Chapter 16, Deploying Java in Standalone Packages and Containers.
Documenting Java classes
Documenting code has always been an issue in almost every language. Java takes a unique approach to encouraging documentation. If you comment your code in a specific format (which we will examine in Chapter 4, Language Fundamentals – Data Types and Variables), the
javadoc tool will generate an HTML page for every class that you create. On this page, you will find all public members of the class presented.
Look at the
javadoc page for the
ArrayList class at https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/ArrayList.html. Everything you see on this web page was written into the source code file that was then converted to the HTML page you are looking at. We will examine this tool in Chapter 11, Documentation and Logging.
jshell tool allows you to write and execute individual Java statements without the need for the usual decorations of classes and methods. This can be quite useful for learning Java. It can execute code line by line as you write it. We will examine
jshell in Chapter 2, Code, Compile, and Execute.
In this chapter, we have learned a little about Java’s history, how it is licensed, and why there are so many distributions and versions of Java. You now understand Java as a development tool and know how to select a Java distribution and version. We saw how we could install Java on our computers regardless of the OS. In Chapter 12, BigDecimal and Unit Testing, we will also examine how to install Java in a Docker container. We wrapped up the chapter with a look at nine Java tools that come with the JDK; we will see them again in later chapters. We will learn more about these tools in those chapters.
In Chapter 2, Code, Compile, and Execute, we will learn how we write, compile, link, and execute Java programs. Coding with a plain text editor,
jshell, and with an integrated development environment (IDE) will be our focus.
- How Java got its name: https://www.quora.com/How-Java-got-its-name/answer/Ashok-Kumar-1682
- GNU General Public License, version 2, with the Classpath Exception: https://openjdk.java.net/legal/gplv2+ce.html
- Oracle No-Fee Terms and Conditions (NFTC): https://www.oracle.com/downloads/licenses/no-fee-license.html
- Java® Development Kit Version 17 Tool Specifications: https://docs.oracle.com/en/java/javase/17/docs/specs/man/index.html
- JVM Garbage Collectors: https://www.baeldung.com/jvm-garbage-collectors