Chapter 4

Understanding the Java Base Platform

by Bryan Morgan


CONTENTS

Before beginning to consider the loftier concepts of the Java language and its use in application development, the new Visual J++ programmer needs to understand the environment in which all Java code runs. The foundation of this environment is referred to as the Java Base Platform, which comprises the following elements:

This chapter explains in detail the constituents of the Java Base Platform, its use, and its location on your machine. This discussion covers a variety of topics, including

Although the Java language has many benefits, perhaps the primary reason for Java's quick success is its promise of platform-independent application development. Since its beginnings, the computer industry has had to accommodate many incompatible computing platforms. Because of these inherent differences, users who shared similar interests generally migrated to similar platforms. In the late 1990s, four primary computing platforms dominate the personal computer market:

Factors such as cost, ease of use, availability, and existing software applications have attracted different groups of users to each of these operating environments. The UNIX operating system is popular in academic environments and many scientific applications are available for it. UNIX is also popular for use as a server because of its scalability and communications features. The Apple Macintosh is popular with a wide range of users, but it is in widest use in the publishing, arts, and education fields because of its intuitive graphical user interface and existing library of software applications. OS/2 is also in wide use, especially in organizations that require seamless connectivity to other IBM computing environments. Microsoft Windows is the leader in terms of number of users and is available in two primary versions: Windows 95 and Windows NT.

As a result of the popularity of these four incompatible operating systems, corporate networking designers have had to deal with a bewildering array of integration problems. Software developers faced with the task of producing applications for use under all of these platforms have had a very limited set of tools to work with. What's more, once developers chose their cross-platform development tools, they were committed to that vendor's cross-platform toolkit and had little opportunity to turn back.

Java eliminates the platform-dependence problem by providing a runtime environment known as the Java Base Platform that is guaranteed to be the same on each operating system. The Java Base Platform resides on each client computer and interprets files containing Java bytecode that can be retrieved from the local machine or from any other computer on the Internet. You will need to understand what bytecodes are before you go on to read about the Java Base Platform later in this chapter.

The Java Runtime Environment

As mentioned in Chapter 1 "Visual J++: What It Is and Why It Is Unique," Java was being developed as the World Wide Web was introduced and the Internet began to grow at a much faster rate than it had ever grown in the past. Because of Java's lofty goals (of being networked and platform independent), Java's designers came to the conclusion that delivering a set of bytecodes to the client machine would result in the best solution.

What is a bytecode, you ask? Bytecodes are the intermediate result when Java source code is compiled. All compilers go through three basic processes: compiling, linking, and executable creation.

Figure 4.1 : The Java compilation process

The compilation process examines source code for syntax errors. As you are probably well aware, if any syntax errors are found, the compilation process ends with an error. After checking the syntax, the compiler checks to make sure that all objects, variables, and methods that the code references are what the code says they are. If the compiler is unable to determine what an object is, it will issue another error and cease to compile. After performing the error-checking routine, the compiler goes through the code again and tries to figure out the best way to convert it into instructions that the computer can understand. Entire books and careers have been built on this topic, so I won't attempt to go into detail. However, the end result of this process is a new version of your source code called bytecode! The Java compiler's job is finished as soon as it writes the bytecode.

Note
The result of this compilation process is a class file in Java. This file is denoted by a .class extension to the source code's original filename. The subject of Java classes was intro-duced in Chapter 3 "Object-Oriented Programming with Java," and will be discussed in much greater detail in Chapter 5 "Elements of the Java Language," and Chapter 6 "Creating Programs with Java."

The linking process links all the newly compiled code modules within the application. In other words, if object A uses object B, object A and object B are initially compiled separately. The objects are combined during the linking stage, which ultimately produces an actual executable program consisting of machine code to be executed by the microprocessor.

Because Java is an interpreted language, the linking and executable file creation processes are deferred until runtime (they will be discussed later in the section titled "The Bytecode Verification Process"). The term interpreted means that an interpreter reads each individual bytecode within the class file and then converts these bytecodes into actual machine instructions. Java uses approximately 250 different bytecodes to denote the basic set of executable instructions. Just as an Intel Pentium or DEC Alpha chip has its own instruction set that represents every instruction built into the chip's silicon, the Java runtime environment has its own instruction set called bytecodes. However, because the Java bytecode specifications (and the class file format) are defined and controlled by Sun, they are exactly the same on every platform that Java runs on.

The Java Class File Format

Each Java class file contains the bytecodes required to implement a specific object in the Java language. Each class file contains the following individual sections:

Although the contents of most of these individual sections are self-explanatory, a few need to be examined in a little more detail. I will answer the most pressing question first: What is "magic"? Interestingly enough, the Magic header represents the first 4 bytes of every class file. To designate that the field being read is in fact a class file, the contents of the Magic number should be 0xCAFEBABE. (Supposedly, this designation refers to certain individuals at a local coffee shop frequented by the Java team and was chosen even before the name "Java.")

The next 4-byte value, the version number, represents the version number of the class file itself. Each Java Virtual Machine (JVM) is cognizant of the maximum version number that it is capable of loading. Should the class file's version number be greater than the JVM's capability, the class file will be rejected.

Because class files are generated and placed on a remote server, in the case of Web applets, the client-side Java runtime system needs to have some methodology for ensuring that the applets being loaded obey all Java security restrictions. Runtime processes known as the bytecode verifier and the class loader do this job.

How Security Is Maintained at Runtime

Once Java bytecodes have been produced in the form of .class files, these bytecodes are ready to be run as an applet or application. Because Java was designed to be a networked language using classes retrieved at runtime from remote servers, security is an integral part of the Java runtime system. Java's designers handled security on three separate levels:

Features needed to be built into the entire runtime system to prevent specially compiled applets from invading remote systems. In other words, nothing could stop an individual from writing a Java compiler that produced bytecodes designed to circumvent the JVM in some way. Remember that Java is an interpreted language. This means that actual memory management for the application is put off until runtime (it is not built into the compiled Java classes). This feature allows Java to run on many different platforms, thanks to the installed JVM. However, it also allows the Java runtime engine to verify that the bytecodes being loaded are, in fact, good bytecodes. This is done using a part of the Virtual Machine known as the verifier.

The Bytecode Verification Process

The bytecode verifier has the unenviable task of checking each bytecode before it is executed (interpreted) to make sure that it is not going to perform an illegal operation. After the bytecode has been verified, the applet is guaranteed to do the following:

The verification process checks many of the things that a good Java compiler will check, but it is important to recognize that the verification process takes place on the client's computer. Security on the server side is virtually meaningless to Internet clients because of the unknown nature of most servers. (This concept clashes with Microsoft's own ActiveX security model that uses "code signing" to give a stamp of approval to a vendor and their ActiveX objects being downloaded. This is discussed in more detail in Chapter 24, "Distributed Component Object Model."

The Java Runtime Class Loader

The set of precautions enforced by the client Web browser (or other applet loader) is done by a part of the Java runtime engine known as the class loader. The class loader does what it says: It loads classes.

Note
The class loader can vary from browser to browser. Security features in Sun's HotJava Web browser allow the user to control security restrictions and even remove them altogether. The Netscape Navigator and Microsoft Internet Explorer browsers offer no user-controlled security measures. Instead, applets are forced into a very rigid set of rules. Therefore, it is probably wise to plan to write applets to conform to the most restrictive case because this will allow them to run on every user's computer.

The class loader can recognize three possible worlds:

The class loader implements defined rules that allow it to intelligently prevent an applet from wreaking havoc on your system. It does this by never allowing a class loaded from a lower level to replace a class existing on a higher level. Although much of the information presented on Java has stated that applets cannot write to a local hard drive or connect to remote computers other than the originating host, this statement is not necessarily correct. For instance, the HotJava Web browser allows users to configure these security restrictions (see Figure 4.2).

Figure 4.2 : The Java applet security screen in HotJava 1.0.

Figure 4.2 allows the HotJava user to loosen or even drop all security restrictions so that applets can do whatever they want when uploaded to your machine. This may be useful in an intranet setting where machines are never connected directly to the Internet, but be very careful otherwise. Undoubtedly, devious applets will be written to do damage to unsuspecting systems. This is why the Netscape Navigator and Microsoft Internet Explorer developers left configurable security features completely out of their product.

Are Java Applets Safe?

As discussed, Java handles security at several different levels. The language is designed in a manner that removes many security holes because it does not allow pointer manipulation. The bytecode verifier is used to verify each uploaded Java class to ensure that it obeys all Java language rules. The class loader enforces security on another level by controlling applet operations at runtime. It is important to realize that the bytecode verifier and class loader both exist on the local system and are part of the Java runtime environment. Because these two components are critical to the success of the Java security model, the user must rely on these components to ensure that Java applets are secure. As the number of third-party virtual machines increases, it is critical that these virtual machines be verified by some independent source to ensure that they operate according to the JVM specification. Sun is currently working on a test suite to do just this. In short: Yes, the Java environment is safe and secure. Vendor-specific implementations, however, must be validated to ensure that they comply with the Java specifications.

Whether developing a standalone application, Web applet, or embedded code, however, two things remain constant no matter where Java runs: the JVM and a standard group of Java classes known as the Java API.

My experience has been that many people are a little intimidated by the JVM, perhaps due to the use of the word machine. The following section explains exactly what the JVM is and what responsibilities it has.

The Java Virtual Machine

Just as a C++ compiler targets code for an Intel microprocessor or a FORTRAN compiler targets binary code to run on a DEC Alpha chip, Java code can be thought of as being targeted to run on the JVM. For this reason, it can be helpful to think of the JVM as a "soft CPU." Although Java is truly platform independent, Java bytecode cannot simply be dropped onto a blank machine and be expected to run. Instead, a virtual computer (thus the name virtual machine) must be available to execute those bytecodes. This virtual computer is, you guessed it, the JVM. In practical terms, the JVM is a piece of software that resides on the machine where Java code is to be run.

The next topic for consideration is the specification for the JVM, which Sun Microsystems controls. Because it isolates Java code from the underlying hardware and software platform, the JVM itself can be explained using a computing platform metaphor. To Java code being executed, the JVM performs both as the operating system and as the hardware platform. Therefore, JVM is described in this context.

The JVM Specification

This specification provides details on exactly what functionality the JVM is to provide so that companies who choose to build JVMs can convert the specification into actual code. Note here that even though Sun controls the specification, it does not create the JVM for every platform. The first JVMs that Sun released were initially available for the Sun Solaris and Microsoft Windows 95/NT operating systems. Since that time, other vendors have provided their own virtual machines for their respective platforms. In some instances, such as Windows 95/NT, several virtual machines are available from different vendors. Information on how to obtain a copy of the JVM for a platform appears later in this chapter. Table 4.1 contains a partial list of platforms that the JVM is available on and the vendors that are officially responsible for providing that platform's reference implementation.

Table 4.1. Reference implementation providers for the Java Virtual Machine.

CompanyOperating System
MicrosoftWindows 95, Windows NT
IBMWindows 3.1
AppleMacintosh
IBMOS/2
Hewlett-PackardHP UX
HitachiHitachi OS
IBMAIX
SGIIrix
SunSolaris
SCOUNIXWare
TandemNon-Stop Kernel
NovellNetWare 4.0
IBMMVS

Table 4.1 shows only the companies that have officially contracted with Sun to provide the reference implementation of the JVM for their specific platform. In fact, many other companies including Netscape Communications currently provide their own versions of the JVM for use with their products. For instance, Microsoft has agreed to provide the reference implementation of the JVM for Windows 95 and Windows NT. This implementation is officially called the Windows Virtual Machine for Java and is the focus of Chapter 18, "The Microsoft Java Virtual Machine."

With Emphasis on the Word Machine

As mentioned earlier, when Java code runs on a computer, it does so "on top" of the JVM. Actually, this virtual machine in many ways mimics a hardware device. Other portions of its architecture can be thought of as resembling an operating system. This section examines the internal workings of the JVM by comparing it to hardware and software platforms.

All microprocessors come with a basic list of possible operations that the microprocessor can perform. Each operation appears to the programmer as a single, atomic unit of work, although in actuality several operations may be occurring "behind the scenes" within the microprocessor. This finite number of operations is known as the microprocessor's instruction set. This instruction set varies from microprocessor to microprocessor and is usually documented in manuals that you can obtain from the chip's vendor.

Programs that use this set of instructions are often referred to as assembly language programs, although these instructions can also be passed directly to the computer using common languages such as C and C++. Like computer hardware, the JVM supports its own finite set of instructions. In fact, a direct parallel can be drawn between a hardware instruction set and the JVM instruction set.

The terms JVM instruction set and bytecodes are synonymous. The JVM supports approximately 250 bytecodes, and each bytecode supports zero or more operands (arguments passed with the instruction). As a compiled Java class runs on the JVM, these bytecodes are processed one line at a time and are eventually converted to machine code to be executed by the actual hardware. Several other interesting parallels can be drawn between the JVM and computer hardware. These parallels are explained in the following paragraphs.

Computer architecture designers often refer to the size of memory that a processor can address as that machine's address space. A chip that uses 16 bits to store memory addresses can address 64KB of memory. The JVM uses a 32-bit value to store addresses and therefore can address 4GB of memory. The size of a single block of memory maintained by the JVM is one byte. A machine's word size is the amount of storage used to transfer data. The JVM uses 32 bits to store a word; therefore, its word size is (surprise!) 32 bits. Unlike actual hardware implementations, the JVM supports a small number of data types. (Many microprocessors' instruction sets simply transfer memory values from location to location without worrying about the actual types of this data.) The JVM supports the following data types:

Coincidentally, you will find in Chapter 5that this basic set of data types is identical to the set of data types supported by the Java language except for the boolean data type (which is actually a byte value to the JVM).

As a microprocessor executes instructions one by one, it maintains a type of scoreboard that always represents the current state of the machine. The actual values, or scores, of program variables are maintained using temporary storage areas located within the microprocessor. Examples of storage elements used to manage this imaginary scoreboard are registers and the stack. Registers are used to store the results of various operations and also memory addresses. The hardware stack stores the parameters and the results of all instructions. Values that are added and removed from the stack are said to be "pushed" and "popped." By now, you shouldn't be surprised to find out that the JVM maintains its own internal registers and stack to perform bytecode operations.

Although the term machine may seem somewhat blunt when referring to what, at first glance, seems like an interpreter, the JVM is in effect a full-featured software microprocessor.

Taking Out the Trash Using Garbage Collection

So far in this chapter, you've seen how the Visual J++ compiler converts your Java source code to bytecodes. These bytecodes are then sent over a wire (either from your hard drive to the JVM or from a Web server's hard drive to the JVM) and are validated by the Java runtime system. Once the code has been verified, the JVM breaks down the bytecodes into a set of machine instructions and executes it.

Believe it or not, because Java is designed to run within a garbage-collecting environment, the JVM's job is not yet done. The term garbage collection refers to the process of automatically cleaning up unused memory when the program is done with it. Most languages that allow programmers to allocate new memory in the form of objects also require the programmer to free the memory. Large amounts of memory that are allocated and never freed can eventually cause a system to slow down to a crawl or halt completely.

Java removes this memory-management chore from the hands of programmers by using the JVM to monitor memory usage at all times during a program's runtime. Java provides this feature for two primary reasons:

The JVM specification in no way specifies how the JVM should free unused memory. Instead, this implementation decision is left up to individual JVM designers. The important feature is that the JVM provides support for runtime garbage collection, which is a two-step process.

The first step in garbage collection requires the JVM to monitor memory usage and determine which objects are subject to being "taken out with the trash." An object is determined to be garbage if it cannot be reached by any currently active branches, or "roots," within the program code. Once these objects have been determined, the JVM must free the memory they are occupying.

Two popular algorithms used to free memory at runtime are the mark-and-sweep and stop-and-copy algorithms. These algorithms are discussed briefly in the following sections because they are excellent examples of different design philosophies and because the Microsoft JVM uses the stop-and-copy approach.

Garbage Collection Using Mark and Sweep

The mark-and-sweep algorithm traverses the entire list of objects available within a program. The algorithm determines which objects are currently active and marks them as such (see Figure 4.3).

Figure 4.3 : Step 1: Mark all active objects.

Once this traversal is complete, all unmarked objects are deleted (see Figure 4.4).

Figure 4.4 : Step 2: Delete all unused objects.

Unfortunately, when objects are dynamically deleted, memory becomes fragmented. To solve the fragmentation problem, the final stage of the mark-and-sweep algorithm compacts the objects in memory by moving objects around in memory (see Figure 4.5).

Figure 4.5 : Step 3: Defragment memory by moving objects.

Many JVM implementations use the mark-and-sweep algorithm. It has the disadvantage of having a high performance overhead because of the large number of object accesses involved. However, this algorithm can operate within a small memory space and is ideal for embedded implementations of the JVM.

Garbage Collection Using Stop and Copy

The stop-and-copy algorithm arrives at the same result as the mark-and-sweep algorithm but usually does so more quickly. However, stop and copy has the disadvantage of requiring a larger amount of heap memory than mark and sweep for its operation because this algorithm requires two equal-sized areas of heap memory at all times. The first area contains all objects used by the program. The second area is used as a "copy buffer." The stop-and-copy algorithm begins by traversing the object list and examining all objects. As soon as an object is determined to be active, it is immediately copied to the second memory area (see Figure 4.6).

Figure 4.6 : Move active memory objects.

Once the JVM reaches the end of the active objects, it switches its focus to the second memory area for all future memory accesses.

The Microsoft Windows Virtual Machine for Java uses the stop-and-copy algorithm to perform garbage collection. This methodology results in much higher performance (compared to the mark-and-sweep algorithm), but it requires twice as much memory as the mark-and-sweep method. From Microsoft's desktop-centric viewpoint, performance is a more important benchmark than memory usage; therefore, this choice makes sense.

This section concludes the discussion of the Java runtime operating environment. The following section examines the Java API in detail and explains the Java Base Platform, its constituents, and its system-level capabilities.

The Java API

The Java Application Programming Interface (API) provides a standard set of objects that all Java programmers can use when developing software. Portions of the Java API are guaranteed to exist in every Java runtime installation. These portions make up what is known as the Java Base API. One of the exciting features of Java is its dynamically linked nature. As has been discussed throughout this chapter, when Java code is compiled, it produces a set of bytecodes that exist in one or more files. One of these class files corresponds to each public Java class implemented in the applet or application. (Don't concern yourself now with the word public. The important point here is that one class file is equivalent to each Java object used throughout your program.)

In the case of a Web-based Java applet, all of the class files that collectively make up your applet could reside together in a directory on a remote Web server. When a client browser loads your applet, all of these class files are transferred over the network to the user's browser (which, by the way, is running an implementation of the JVM). If you have loaded applets in the past into a Web browser, you know that some time was spent downloading these class files before the applet was actually displayed and executed. The Java API greatly reduces this download time because the API probably includes the majority of the objects that your applet uses.

For instance, imagine an applet that contains a list box, a button, and text on the screen. Because Java is an object-oriented language, this screen is created using the List, Button, and Label objects contained within the Java Base API. When your code is compiled, one class file will be generated to be placed on the Web server. After a user loads a page containing your Java applet, your solitary class file will be downloaded to his or her machine and will be linked with local copies of the List, Button, and Label class files.

The beauty of this process is that Java programmers can not only produce bytecodes that run on all operating platforms, but also produce source code that does not need to be modified for any particular platform. Developers can distribute applets or applications with the knowledge that each machine using their software will contain a common base set of Java bytecodes known as the Java Base API.

The Java Base API

The Java Base API is currently defined as the full set of APIs that is distributed with the Java Developer's Kit, or JDK, version 1.0.2.

Note
The JDK contains the Java Base Platform and a rudimentary set of development tools that can be used for Java development. More information on the JDK is provided in the section titled "Obtaining the Java Base Platform."

The Java Base API provides an incredibly useful code base for Java developers. Classes in the Base API, or Java Applet API as it is also called, provide the functionality used for common input/output, networking, graphical user interfaces, and applet operations. These classes are part of the java package. (A package is simply a Java construct for an object used to group a set of related classes.) The java package contains the following subpackages:

Each package contains a myriad of classes that are most commonly used by Java developers. Brief discussions of the individual packages follow. For more detailed information on the java package, see Chapter 13, "The Standard Java Packages," which is dedicated to this topic.

This list of packages collectively make up the Java Base API. As Java expands, more and more classes will be added to the different packages so that enhanced functionality can be passed on to the end user. Many future packages are currently contained in the Java Standard Extension API.

The Java Standard Extension API

The Java Standard Extension API provides a standard API that is published and open. Because members of the Extension API are not included with the Java Base Platform, individual vendors are encouraged to implement their own versions of these APIs as long as they conform to Sun standards. Sun is currently considering adding some of the more popular Extension APIs to the Base API. (These APIs are noted in the following sections.)

The Java Security API

The Java Security API is being designed to provide a modular approach to implementing security for Java applications. Consequently, security models will be able to be swapped in and out should better methods be chosen. For instance, a plug-in architecture such as this would allow developers to quickly switch between different encryption schemes should more superior schemes be introduced in the future. The Java Security API will provide digital signatures, encryption, and authentication of Java code. The Java Security API is being considered for migration to the Java Base API.

The Java Media API

The Java Media API is being designed to provide complete multimedia capabilities for use in Java application development. It includes APIs for animation, collaboration, 2D and 3D graphics, video, audio, and telephony. The 3D API is eagerly awaited by many because it provides support for VRML. Tools for collaboration will be provided with the Share API, which should allow developers to add collaboration capabilities to their applications. Portions of the Java Media API being considered for addition to the Java Base API include the Audio, 2D, and Animation APIs.

The Java Commerce API

The Java Commerce API provides secure commerce capabilities through the use of Java. A key component of the Java Commerce API is the Java Wallet. This object will allow clients to use a digital wallet containing identification information, credit cards, and cash. Powerful security features are naturally part of this API, and their implementation is essential to the success of secure commerce using Java. This API is being considered for addition to the Java Base API.

The Java Server API

The Java Server API will provide capabilities that can be used for the creation of Java-based Internet and intranet servers. This API includes libraries for system administration, security, and resource monitoring.

The Java Enterprise API

The Java Enterprise API is arguably the most eagerly awaited of all the Java standard extensions. Included in the Enterprise API is a group of frameworks that support Java database connectivity (JDBC), Interface Definition Language (IDL), and Remote Method Invocation (RMI).

JDBC is currently available and is the Java equivalent of Microsoft's open database connectivity (ODBC) API. JDBC will provide database connectivity and uses a driver-based system to communicate with SQL database servers such as Oracle, SQL Server, and Informix.

IDL is a language-independent way of exposing an object's methods and properties to other object models on different platforms. The IDL is used by common object request brokering architecture (CORBA) to define properties of objects.

RMI is the object world's equivalent of remote procedure calls (RPCs). RMIs are used to call objects located on remote machines.

Of the three APIs included within the Java Enterprise API, JDBC is the only one currently being considered for inclusion with the Java Base API.

Obtaining the Java Base Platform

By now you should have a good understanding of how the Java runtime system operates through the combination of the Java Base API and the underlying JVM. You can obtain the Java Base Platform in three different ways:

If you are reading this book, you are probably most interested in the Java Base Platform provided with Visual J++, which is discussed in the next section. If you are interested only in viewing Java applets, install a Java-capable Web browser. Once this installation is complete, a copy of the Java Base Platform will exist somewhere on your system. (The exact location depends on which browser you install.) However, if you do not yet have a copy of Visual J++ but are interested in developing Java code, you can use the JDK to compile and run many of the examples in this book. This toolkit is freely provided by Sun Microsystems and is currently available for Windows 95/NT, Apple Macintosh, and Sun Solaris.

Let me stress that the tools and documentation included in the JDK are rudimentary at best. A tremendous effort will be made throughout this book to point out the many strengths and capabilities of the Microsoft Visual J++ compiler. In fact, all discussions and examples involving Microsoft COM or ActiveX technologies are applicable only to Visual J++. In the future, other tools will undoubtedly be released that support these technologies, but for now Microsoft leads the pack. Of course, it certainly doesn't hurt to have the ActiveX, Windows Virtual Machine for Java, and Visual J++ designers working within the same organization!

Assuming that you have already chosen to install the Visual J++ development platform, the next section discusses the physical components on your machine. Examining the Java Base Platform in detail should remove some of the mystique surrounding Java and its runtime execution environment. Other items installed as part of Visual J++ are also explained briefly. Many of these items will be explained in much greater detail throughout the remainder of this book.

Examining the Visual J++ Installation

As mentioned earlier, the Java Base Platform has three basic components:

Visual J++ installs all three components onto your local machine in different forms.

The runtime interpreter is installed in the form of the JVIEW.EXE application. JView can be located in the Visual J++ \bin directory. This interpreter accepts a Java class name as its command-line input (jview classname). If the class is a valid Java application class (see Chapter 8 "Developing Applets and Applications," for more information on Java applications), JView will act as the runtime interpreter for the application. For Java applets and ActiveX controls embedded in Web pages, the Web browser itself supplies the runtime interpreter. This runtime component varies from browser to browser.

The Microsoft Windows Virtual Machine for Java is actually distributed throughout the c:\windows directory. However, several Windows Registry keys can be examined to determine the location of required components. To examine the Registry under Windows 95, run REGEDIT.EXE. Under Windows NT, run REGEDT32.EXE. Examples of keys that can be found in the HKEY_LOCAL_MACHINE\Software\Microsoft\Java VM Registry entry are

The Windows Virtual Machine also examines the CLASSPATH environment variable in addition to the ClassPath Registry key to determine the location of all class files.

The Java Base API is also included with the Visual J++ installation. The classes in the Base API are zipped into a file named CLASSES.ZIP located in the c:\windows\java\classes directory. If for some reason the CLASSES.ZIP file is not located in that directory, examine the ClassPath Registry key to get an idea of where it might be located.

Summary

The Java Base Platform is a well-defined subset of Java technologies that is guaranteed to be the same on every platform. This sort of standardization is extremely important in a world where every company is racing to add features to "standardized" technologies. Any application or applet that is written to run using the Java Base Platform will be guaranteed to run on every Java-enabled operating system.

The Java Base Platform is composed of a runtime engine that is responsible for validating Java bytecodes as they are received. The JVM then translates these bytecodes into machine code. When Visual J++ is installed, the user also receives the Sun-certified copy of the Microsoft Windows Virtual Machine for Java. This JVM is the reference implementation for the Windows platform. Any changes Microsoft makes to this JVM can then be licensed back to Sun for inclusion in JVMs on all other platforms.

In addition to the Java Base API, Sun is continually developing new Java APIs in the hope that Java can gain enough broad support to become the programming language and environment of choice for all development. The key point of this chapter is that Visual J++ is fully compatible with all capabilities of Java. Bytecodes produced by Visual J++ will run on any platform that contains a JVM (unless Java is combined with ActiveX). The following chapter introduces the basic syntactical elements of the Java programming language. Following Chapter 5 the concepts introduced in the first five chapters will begin to be applied to developing actual Java applets and applications through the remainder of Part I, "Introduction to Java Programming Using Visual J++."