This book will be your guide to achieving an intermediate level of Java programming skills. Programming is not just about knowing the language syntax. It is also about the tools and sources of information necessary to write, compile, and execute a program or run a whole software system. The first step on this road is to learn the important components of Java, including Java Development Kit (JDK) and Java Virtual Machine (JVM).
This chapter will introduce Java as a language and a tool, and establish the most important terminology. It will also describe the motivation behind Java's creation, cover its history, editions, versions, and technologies, and outline Java's marketing position and main areas of application. Then, a sequence of practical steps will walk readers through the process of Java installation and configuration on their computers, and introduce the main Java commands.
In this chapter, we will cover the following topics:
- What is Java?
- Java platforms, editions, versions, and technologies
- Java SE Development Kit (JDK) installation and configuration
- Main Java commands
- Exercise – JDK tools and utilities
Since this book is written for beginners, we will assume that you know almost nothing about Java. But even if you do know something, or even a lot, it is always helpful to review the basics, even if it's just so you can feel good about yourself by appreciating how much you have mastered already. So, we will start by defining the terms Java, JVM, compilation, bytecode, and more.
When talking about Java, people use Java, JVM, JDK, SDK, and Java platform as synonyms. The legal definition treats Java as Sun's trademark for a set of technologies, but we typically do not think about Java as a trademark. Most often, when somebody says Java, they mean a programming language that is used by humans to express sets of instructions (programs) that can be executed by a computer (not directly, but after the program is compiled/transformed into code that a computer understands). The human-readable Java program is called source code, and the computer-readable program (after all transformations) is called binary code, because it is expressed only using 1 and 0.
You can find the complete Java Language Specification (description) at https://docs.oracle.com/javase/specs/. It is much more accessible than one might expect, and it can be helpful even for a novice, especially if one uses it as a reference document. Do not feel discouraged by the formal language of the first few sections. Read what you can and come back later, as your understanding of Java grows and the motivation for deeper and more precise definitions increases.
Have you noticed that there are two similar terms, bytecode and byte code? In conversation, the difference is hardly noticeable, so people use them interchangeably. But there is a difference. Byte code (or Byte Code, to be precise) is a language that can be executed by a special program called JVM. By contrast, bytecode is the format (each instruction occupies one byte, thus the name) of the instructions generated by the Java compiler (another program) that reads the human-readable source code and transforms it into Byte Code.
Bytecode is a binary code expressed in the format JVM understands. JVM then reads (loads, using a program called class loader) bytecodes, transforms the instructions into binary code (instructions in a format a particular computer microprocessor, where JVM is running, understands), and passes the result to the CPU, a microprocessor that executes it.
A class is a file (with the extension .class) produced by the Java compiler (from the source code in a file with the same name and the extension .java). There are more than a dozen JVM implementations, created by different companies, but we will be focusing on Oracle JVM's implementation, which is called HotSpot. In Chapter 11, JVM Processes and Garbage Collection, we will look more closely at JVM's functionality, architecture, and processes.
On the same page as the Java Language Specification (https://docs.oracle.com/javase/specs), you can find the Java Virtual Machine Specification. We recommend that you use it as a source of references for the terminology and for the understanding of JVM functionality.
Since Java 9, applets (components that can be executed in a browser) are not supported anymore, so we will not talk much about them. An application is a Java program that can be (after compilation) executed on a computer where JVM is installed. So, JDK includes at minimum a compiler, JVM, and Java Class Library (JCL)—a collection of ready-to-use procedures that can be called by an application. But in reality, it has many other tools and utilities that can help you to compile, execute, and monitor a Java application. The subset of JDK that includes JVM, JCL, class loader, and supporting files allows the execution (running) of bytecode. Such a combination is called the Java Runtime Environment (JRE). Each Java application is executed in a separate JVM instance (copy) that has its own allocated computer memory, so two Java applications cannot talk to each other directly, but only via the network (web-services and similar means).
So, when people use SDK in reference to JDK, they are correct, but not precise.
The supporting libraries in the preceding definitions are Java standard libraries, also called JCL, and are necessary for executing bytecode. If a program requires some other libraries (not included in JCL), they have to be added at compilation time (see Chapter 3, Your Development Environment Setup, which describes how to do it) and included in the generated bytecode. Java platform can be one of the four: Java Platform Standard Edition (Java SE), Java Platform Enterprise Edition (Java EE), Java Platform Micro Edition (Java ME), or Java Card. There used to be the JavaFX Platform, too, but it has been merged into Java SE since Java 8. We will talk about the differences in the next section.
These are the most basic terms. Other terms will be introduced as needed throughout the book, in the corresponding contexts.
Java was first released in 1995 by Sun Microsystems. It was derived from C and C++, but did not allow users to manipulate computer memory on a very low level, which is the source of many difficulties, including memory leak related issues, that C and C++ programmers experience if they are not very careful about it. Java stood out due to its simplicity, portability, interoperability, and safety net, which allowed it to become one of the most popular programming languages. It is estimated that as of 2017, there are close to 20 million programmers in the world (close to 4 million of them are in the US), and approximately half of them use Java. And there are good reasons to believe that the need for software developers, including Java developers, will only grow in the future. So, studying Java looks like a step towards a stable career. And learning Java is not actually very difficult. We will show you how to do it; just continue reading, thinking, and trying all the suggestions in practice on your computer.
Java was conceived as a facility that allows users to write once, run anywhere – that is another term to explain and understand. It means that compiled Java code can run on all computers with operating systems that support Java, without the need for recompilation. As you understand already, support Java means that for each operating system, an interpreter exists that can transform bytecode into binary code. That's how run anywhere is implemented: anywhere where a Java interpreter is available.
After the concept proved to be popular and Java was firmly established as one of the major players among other object-oriented languages, Sun Microsystems made much of its JVM free and open source software, governed by the GNU General Public License (GPL). In 2007, Sun Microsystems made all of its JVM's core code available under free and open source distribution terms, except for a small portion of code to which Sun did not have the copyright. In 2010, Oracle acquired Sun Microsystems and declared itself a steward of Java technology with a relentless commitment to fostering a community of participation and transparency.
Today, Java is used in many areas, most prominently in Android programming and other mobile applications, in various embedded systems (various chips and specialized computers), desktop Graphical User Interface (GUI) development, and a huge variety of web applications, including network applications and web services. Java is also widely used for scientific applications, including the rapidly expanding areas of machine learning and artificial intelligence.
There were five primary goals in the creation of the Java language, according to Design Goals of the Java TM Programming Language (http://www.oracle.com/technetwork/java/intro-141325.html). The Java language had to be:
- Object-oriented and familiar: This meant that it had to look like C++, but without unnecessary complexities (we will discuss the term object-oriented in Chapter 2, Java Language Basics)
- Architecture-neutral and portable: This meant the ability to use JVM as the environment that isolates the language (source code) from the knowledge of each particular operating system (often called the platform)
- High performance: It should work on par with the leading programming languages of the time
- Interpreted: It can be moved to an executing phase without linking (creating a single executable file from multiple .class files), thus allowing a quicker write-compile-execute cycle (modern JVMs, though, are optimized to keep the binary version of the often used .class files, to avoid repeating interpretation)
- Multithreaded: It should allow several concurrent execution jobs (threads), such as downloading an image and processing other user commands and data at the same time
- Dynamic: Linking should happen during execution
- Secure: It had to be well protected from an unauthorized modification at runtime
The result proved these goals to be well-defined and fruitful, because Java became one of the main languages of the internet era.
In everyday discussions, some programmers use these terms interchangeably, but there is a difference between Java platforms, editions, versions, and technologies. This section is focuses on explaining it.
We hear the term platform almost every day. Its meaning changes depending on the context, but in the most general sense, it means a device or environment that allows someone to do something. It serves as a foundation, an environment, a platform. In the information technology realm, a platform provides an operating environment where a software program can be developed and executed. An operating system is a typical example of a platform. Java has its own operating environment, which comes, as we have mentioned in the previous sections, in four platforms (and six editions):
- Java Platform Standard Edition (Java SE): This is the edition most people mean when they say Java. It includes JVM, JCL, and other tools and utilities that allow for the development and deployment of Java applications on desktops and servers. In this book, we are going to stay within the boundaries of this edition, and will mention the other editions only in this section.
- Java Platform Enterprise Edition (Java EE): This is composed of Java SE, servers (computer programs that provide services to the applications), enhanced libraries, code samples, tutorials, and other documentation for developing and deploying large-scale, multitiered, and secure network applications.
- Java Platform Micro Edition (Java ME): This is a small-footprint (using little resources) subset of Java SE, with some specialized class libraries for developing and deploying Java applications for embedded and mobile devices – phones, personal digital assistants, TV set-top boxes, printers, sensors, and so on. There is also a variation of Java ME for Android programming (with its own JVM implementation), developed by Google. It is called Android SDK.
- Java Card: This is the smallest of the Java platforms, for developing and deploying Java applications onto small embedded devices, such as smart cards. It comes in two editions (quotes are taken from the official Oracle documentation found at http://www.oracle.com/technetwork/java/embedded/javacard/documentation/javacard-faq-1970428.html#3):
- Java Card Classic Edition, which
targets smart cards as deployed today on all vertical markets, based on ISO7816 and ISO14443 communication.
- Java Card Connected Edition, which is developed
to support a web application model, with servlets running on the card, and TCP/IP as basic protocoland
runs on high-end secure microcontrollers, typically based on a 32-bit processor and supporting a high-speed communication interface like USB.
- Java Card Classic Edition, which
Since its first release in 1996, Java has evolved through nine major versions:
- JDK 1.0 (January 23, 1996)
- JDK 1.1 (February 19, 1997)
- J2SE 1.2 (December 8, 1998)
- J2SE 1.3 (May 8, 2000)
- J2SE 1.4 (February 6, 2002)
- J2SE 5.0 (September 30, 2004)
- Java SE 6 (December 11, 2006)
- Java SE 7 (July 28, 2011)
- Java SE 8 (March 18, 2014)
- Java SE 9 (September 21, 2017)
- Java SE 10 (March 20, 2018)
There are several suggestions regarding changing the Java versioning scheme. Since Java 10, a new time-based versioning $YEAR.$MONTH of JDK has been introduced. Also, a new Java version is planned to be released every six months, in March and in September of each year. So, Java 11 will be released in September 2018, with JVM version 18.9. We will show you how to display which JDK version you are using shortly.
The word technology is overloaded. Programmers use it for almost anything. If you look at Oracle's list of Java technologies (https://www.oracle.com/java/technologies/index.html), you will find the following list:
- Embedded, which includes all of the previously listed Java platforms except for Java EE, with some modifications, usually with a smaller footprint and other optimizations
- Java SE, which covers Java SE and Java SE Advanced, which includes Java SE and some monitoring and management tools for an enterprise level (larger than just a development computer) installation
- Java EE, as described previously
- Cloud, which includes cloud-based reliable, scalable, and elastic services
But in the Oracle glossary (http://www.oracle.com/technetwork/java/glossary-135216.html), the following technologies are added to the list:
- JavaSpaces: A technology that provides distributed persistence
- Jini Technology: An Application Programming Interface (API) that enables the networking of devices and services automatically
Elsewhere, on the front page of the Oracle Java 10 documentation (https://docs.oracle.com/javase/10), client technologies are listed as follows:
Meanwhile, in the Oracle Java tutorial (https://docs.oracle.com/javase/tutorial/getStarted/intro/cando.html), Java Web Start and Java Plug-In are mentioned as deployment technologies
for deploying your applications to end users.
However, the biggest list of Java technologies that Oracle provides is on the page dedicated to the Technology Network (http://www.oracle.com/technetwork/java/index.html). In addition to Java SE, Java SE Advanced and Suite, Java Embedded, Java EE, Java FX, and Java Card, there are also listed Java TV, Java DB, and Developer Tools. If you go to the Java SE or Java EE pages, under the Technologies tab, you will find more than two dozens APIs, and various software components listed as technologies, too. So, one should not be surprised to find anywhere any kind of list of Java technologies.
It seems that anything related to Java has been called a technology at least once, somewhere. To avoid further confusion, from now on, in this book, we will try to avoid using word technology.
From now on, every time we talk about Java, we mean Java SE version 10. We will refer to it as Java 10, or Java, or JDK, used as synonyms, unless otherwise specified.
Before you can do any Java development on your computer, you will need JDK installed and configured. In order to do this, search the internet for the JDK download and select any link that starts with https://www.oracle.com/. The best, as of this writing, should be http://www.oracle.com/technetwork/java/javase/downloads/index.html.
If you follow the preceding link, you will see this section:
Let us call this page Page1, for further references. Now, you can click the Download link under JDK. The other two download links offer JRE, which, as you know already, only allows you to run already compiled Java programs; we need to write a program, compile it into bytecode, and then run it.
After you click, you will see a page (Page2) with this section:
These are the Java installers for different operating systems (OS). You need to choose the one that fits your OS and click the corresponding link (do not forget to click Accept License Agreement using the radio button; if in doubt, read the license agreement via the link Oracle Binary Code License Agreement for Java SE). For Linux, there are two installers – one in Red Hat Package Manager Format (.rpm), and one that is just an archived (.tar) and compressed (.gz) version. Also, noticed that in this list, there are only installers for 64-bit operating systems. As of this writing, it is not clear yet if the 32-bit version is to be dropped officially, although it was available as an early access build.
Select the installer that you need, and download it.
Now is the time to install Java, which basically consists of the following four steps:
- Expand the installer
- Create directories
- Copy files into these directories
- Make the Java executables accessible without typing the full path
To find the detailed installation instructions, go back to Page1 and click on the Installation Instructions link. Find the link for your operating system and follow the provided steps, but choose only those that are related to JDK.
Eventually, you will come to the point when you are able to run the command java -version, which will display the following:
As you can see, it shows the version for Java as 10.0.1, and for JRE and JVM as 18.3 (build 10.0.1). It is not clear yet if future versions of Java, JRE, and JVM are going to follow the same format.
Anyway, if the java -version command displays the version you tried to install, it means that you have installed Java correctly and can now enjoy working with it. From now on, every time a new version comes out, you are going to be prompted to upgrade, and you can do it by just clicking the provided link. Alternatively, you can go to the page with the installers (Page2), download the corresponding installer, launch it, and repeat the process already familiar to you.
In practice, though, programmers do not upgrade their Java installation every time. They keep their development version the same as the Java in their production environment (in order to avoid potential incompatibility). If they would like to play with a new version before upgrading the production, they might have two versions of Java installed on their computer, in parallel. In Chapter 3, Your Development Environment Setup, you will learn how to do this, and how to switch between them.
In the previous section, you saw one example of a Java command, the one that displays the JVM version. By the way, the command java starts the JVM, and is used to run bytecodes of the compiled Java programs (we will demonstrate how to do this in detail in Chapter 4, Your First Java Project).
Now, if you only run java, the output will display the short version of help. Since it is quite long, we will show it in several parts. Here is the first section:
It shows three ways to run JVM:
- To execute a class, a .class file that contains bytecode
- To execute a jar file, a file with the extension .jar that contains .class files (may be even the whole application) in a ZIP format, which also includes a Java-specific manifest file
- To execute the main class in a module (a group of .class files and other resources that is better structured than a .jar file), typically an application, or a part of it
As you can see, in each of the preceding commands, a main class has to be supplied explicitly. It is the .class file that has to be executed first. It acts as the main entrance into the application, and starts the chain of loading other classes (as they are needed) to run the application. An example of such a command would be:
In fact, this means that there is a file, MyGreatApplication.class, in the current directory, but we should not specify the file extension. Otherwise, JVM will look for the file MyGreatApplication.class.class, which it will not find, of course, and fail to run anything.
In this book, we are not going to use any of these commands explicitly, and will leave it up to the editor to run it behind the scenes, because a modern editor does not just help write and modify the source code; it can also compile and execute the written code. That's why it is called not just the editor, but the Integrated Development Environment (IDE).
Nevertheless, we will continue to overview all of the java command options, so you will have an idea what is going behind the scenes in your IDE. To enjoy car driving, one does not need to know the details of the engine's inner workings, but it is helpful to have some idea about the principles of its operation. Besides, as your professional level grows and the applications you work on grow too and have to handle many requests, you will need to adjust the JVM configuration, so here is the first sneak peek under the hood.
Here is the next section of the output of the java command:
In the preceding screenshot, you can see two deprecated options followed by options related to classpath and module path. The last two are very important options. They allow the specifying of the location of the classes your application consists of, and the location of the libraries your application uses. The latter can be classes written by you or third-party libraries.
The concept of modules is out of the scope of this book, but module path is used very similarly to the classpath. The classpath option tells JVM where to look for the classes, while the module path tells JVM about the location of the modules. It is possible to use both in the same command line.
For example, let us assume that you have the file MyGreatApplication.class (which contains the bytecode of your program, MyGreatApplication.java) stored in the directory dir2, which is a subdirectory of the directory dir1, and your terminal window currently shows the content of the directory dir1:
As you can see, there is another directory, dir3, which we created to store another file, SomeOtherProgram.class, that is used by your application. We also put in dir4 a library of other supporting .class files, collected in SomeLibrary.jar. The command line to run your application then looks like this:
java -cp dir2:dir3:dir4/SomeLibrary.jar MyGreatApplication //on Unix
java -cp dir2;dir3;dir4\SomeLibrary.jar MyGreatApplication //on Windows
Alternatively, we can put SomeOtherProgram.class and MyGreatApplication.class in some.jar or a some.zip file, and place it in dir5. Then, the command will take one of the following forms:
java -cp dir4/SomeLibrary.jar:dir5/some.zip MyGreatApplication //Unix
java -cp dir4/SomeLibrary.jar:dir5/some.jar MyGreatApplication //Unix
java -cp dir4\SomeLibrary.jar;dir5\some.zip MyGreatApplication //Windows
java -cp dir4\SomeLibrary.jar;dir5\some.jar MyGreatApplication //Windows
Instead of -cp, we could use the options -classpath or --class-path. They are just three different conventions, so that people used to one of them can write a command line intuitively. None of the styles are better or worse than the others, although each of us has preferences and opinions. If neither of the classpath options is used, JVM looks for classes only in the current directory. Some of the classes (standard libraries) are always located in certain directories of Java installation, so there is no need to list them with a classpath option. We will talk about setting the classpath in more detail in Chapter 3, Your Development Environment Setup.
The next section of the java command output lists options that allow for validating that everything is set correctly before actually executing the application:
Since modules are outside of the scope of this book, we are skipping these and moving on to the next section of the output:
The -D option allows for setting a parameter with a value that is accessible to the application. It is often used to pass some values or flags to the application, which the application can use to change its behavior. If more information needs to be passed, then the .properties file is used (with many flags and various values), while the location of the property file is passed with the option -D. It is completely up to the programmer what has to be in the .properties file or in the value passed with the option -D. But there are best practices related to the application configuration, which also depend on the particular framework or libraries you are using. You will learn them over time, and these practices are beyond the beginner programmer course.
The -verbose option provides more information (than we have seen on these screenshots) and some specific data, depending on the flags class, module, gc, or jni, where gc stands for garbage collector, which will be discussed in Chapter 11, JVM Processes and Garbage Collection. For the other flags, you can read the official Oracle documentation, but chances are, you will not use them anytime soon.
The -version option displays the version of Java that is installed. This is very useful from day one, because it allows for checking, at any time, what version of Java is currently in use. In the previous section, we demonstrated how to do it, and the output it produces. When a new version of Java is released, many programmers install it in parallel with the one they are currently using, and switch between them, either to learn new features or to start writing code for a new version, while maintaining the old code written for the old version. You will learn how to have two versions of Java installed on the same computer, and how to switch between them, in Chapter 3, Your Development Environment Setup.
We will skip the module-related options.
The rest of the options in the preceding screenshot are related to the help. The options -?, -h, -help, and --help display what we are showing in these screenshots, and the options -X and --help-extra provide additional information. You can try all of them on your own.
The last section of the help output looks as follows:
We will not discuss these options. Just note how to use the long option (with two hyphens) explained in the last preceding line.
As mentioned earlier, a program written in Java is called a source code, and is stored in a .java file. The compilation command javac reads it and creates a corresponding .class file with Java Byte Code.
Let us run the command javac without specifying a .java file. It will show help. Let us review it in sections:
The help tells us that this command has the following format:
javac <options> <source files>
To compile just a few files, one can list them in the command line after options (if the file is not in the current directory, one has to prepend the filename with an absolute or relative path). Listed files are separated by colons (:) for Oracle Solaris, or semicolons (;) for Windows, and can be directories, .jar files, or .zip files. It is also possible to list all source files in a file and provide this filename using the @filename option (see the preceding screenshot). But do not try to remember all of this. You will rarely (if ever) run the commands java or javac explicitly. You will probably use an IDE that will do it for you (see Chapter 3, Your Development Environment Setup). That is also the reason we are going to skip most of the options listed in the preceding screenshot and will mention only two of them: --class-path (or -classpath, or -cp), which specifies where to find the .class files required by the currently compiled code, and -d, which indicates where to put the created .class files.
Here is the next section of javac help:
The only option from the preceding screenshot that we will mention here is --help (or -help), which provides the same help message that we are going through now.
Finally, the last section of javac help is as follows:
We have already described the option --source-path (or -sourcepath). The option -verbose asks the compiler to provide a more detailed report about what it is doing, while the option --version (or -version) displays the JDK version:
There are more than a dozen other Java commands (tools and utilities) that you will only start using probably after several years of professional programming, if at all. They are all described in the Oracle Java documentation online. Just search the Java utilities and tools.
Among them, we find only one command that is very useful from day one of Java programming. It is the command jcmd. If you run it, it displays all of the Java processes (JVM instances) that are running on your computer. In this example, you can see three Java processes, with the process IDs 3408, 3458, and 3454:
Process 3408 runs the Maven server (your IDE will typically start it). Process 3458 is our running of jcmd. And process 3454 is an editor (IDE) IntelliJ IDEA that is running the small demo application com.packt.javapath.App.
This way, you can always check to see if there is a runaway Java process on your computer. If you would like to stop it, you can use a Task Manager, or the command kill, which requires PID.
Knowledge of PID is also needed when you would like to monitor your Java application. We will talk about that in Chapter 11, JVM Processes and Garbage Collection.
With this, we complete our overview of Java commands. As we already mentioned, your IDE will use all of these commands behind the scenes, so you will probably never use them unless you do production support (which is several years out, after you start learning Java). But we feel that you need to know them, so that you can connect the dots of the Java development process.
On your computer, find the Java installation directory, and list all of the commands (tools and utilities)—the executables—present there.
Here is the list of all of the executables installed with Java 10.0.1:
One of the ways to find this directory is to look at the value of the environment variable PATH. For example, on a Mac computer, Java is installed in the directory /Library/Java/JavaVirtualMachines/jdk-10.jdk/Contents/Home/bin.
The Oracle documentation that describes the JVM installation location can be found at https://www.java.com/en/download/help/version_manual.xml.
In this chapter, you have learned the most important Java related terms—JVM, JDK, SDK, Java platform, and others, covering the main phases of a Java program's life cycle, from source code to bytecode to execution. You also learned about Java's history, the motivation behind its creation, its editions, and its versions. The practical steps and advice provided have helped you to install Java on your computer and exercise its main commands, java, javac, and jcmd. For more details, you were referred to the official Oracle documentation. The ability to find and understand this documentation is a prerequisite for a successful career as a Java programmer, so we recommend that you follow all of the provided links and do some related searching on the internet, so that you feel comfortable finding good sources of information.
In the next chapter, we will dive into Java as a programming language, and will cover the basics. This will become a foundation (or a jumping board, if you will) for the following chapters. If you are new to Java, we recommend that you continue reading without skipping, because each chapter is built on knowledge from the previous one. Even if you have some Java exposure, it is always helpful to review the basics again. Repetitio est mater studiorum (Repetition is the mother of study/learning), says a Latin proverb.