24.1 INTRODUCTION
The programming API is an API that let users to write scripts and programs to manipulate virtual machines. It is a high-level interface which is easy to use and practical for both script developers and application programmers.
The Java platform has two main parts, the Java virtual machine and the Java API, as shown in Figure 24.1.
1. Java virtual machine
The Java virtual machine is a 'soft' computer that can be implemented in software or hardware. It is an abstract machine designed to be implemented on top of existing processors. The porting interface and adapters enable it to be easily ported to new operating system without being completely rewritten.
2. Java API
The Java API forms a standard interface to applets and applications, regardless of the underlying operating system. The Java API is the essential framework for application development. This API specifies a set of essential interfaces in a growing number of key areas that developers will use to build their Java-powered applications.
The Java base API : It provides the very basic language, utility, I/O, network, GUI and applet services; OS companies that have licensed Java have contracted to include them in any Java platform they deploy.
The Java standard extension API : It extends the capabilities of Java beyond the Java base API. Some of these extensions will eventually migrate to the Java base API. Other non-standard extension APIs can be provided by the applet, application or underlying operating system. As each new extension API specification is published, it will be made available for industry review and feedback before it is finalized.
In Figure 24.1, the Java base platform is the part shown in black, including the blocks labelled Adapter (platform dependent). The Java API includes both the Java base API and Java standard extension API. The classes are the implementation of that API. The Java virtual machine is at the core of the platform. The porting interface lies between the Java virtual machine and the operating system (OS) or browser. This porting interface has a platform independent part as shown in black and a platform dependent part shown as adapters. The OS and JavaOS provide the window, filling and network functionality. Different machines can now be connected by a network.
The Java API framework is open and extensible. The API is organized by groups or sets. Each of the API sets can be implemented as one or more packages which are called as namespaces. Each package groups together a set of classes and interfaces that define a set of related fields constructors and methods.
24.2 VIRTUAL MACHINE
The Java virtual machine is key to the independence of the underlying operating system and hardware; it is a platform that hides the underlying operating system from Java-powered applets and applications. And it is very easy to port the virtual machine to a browser or another operating system.
In addition, the virtual machine defines a machine independent format for binary files which is called as '.class' file format. This format includes instructions for a virtual computer in the form of bytecodes. The bytecode representation of any Java language program is symbolic in that it offsets and indexes into methods that are not constants, but are instead given symbolically as string names. The first time a method is called, it is searched by name in the class file format, and its offset numeric value is determined at that time for quicker access at subsequent lookups. Therefore, any new or overriding method can be introduced late at runtime anywhere in the class structure and it will be referred to symbolically, and properly accessed without breaking the code.
Now, on the basis of the example given in the above Java application program named JPS2.java, the working of Java virtual machine will be traced. The Java virtual machine (simple virtual machine) can be categorized into five fundamental pieces as shown in figure 24.2.
Some of these pieces might be implemented by using an interpreter 'java' or native binary code compiler—Java native interface (JNI) or by a hardware chip.
The remarkable point here is that the memory areas required by the Java virtual machine are not just required at any particular place in the memory (primary or secondary), or to be in any fixed order. However, all but the method area must be able to represent align 32-bit values (Java stack is 32-bit wide).
Now, the pieces of Java virtual machine can be shown in Figure 24.2.
Java Bytecodes
To get the bytecode for any application implemented in Java, the Java application will first be compiled using 'javac'. For getting the concept of byte code compile the above file (JPS2.java) using javac.
After compiling the Java program using 'javac' the '.class' file format is obtained which contains the bytecodes which makes the program platform independent. To see the bytecodes the javap will be used with option '–c'.
javap - c filename>filename.bc
A Java virtual machine starts execution by invoking the method main of some specified class, passing it a single argument, which is an array of strings (public static void main(String args[])
). This causes the specified class to be loaded, linked to other types that it uses and initialized. The method main
must be declared public, static, and void. Below the file 'JPS2.class' is given that contains the bytescode as given below:
The bytecodes are a high-level representation of the program so that optimization and machine code generation (via a just-in-time compiler ) can be performed at that level. In addition, garbage collection can occur inside the virtual machine, since it holds variables in stacks in the Java platform address space.
A bytecode instruction consists of a one-byte opcode that serves to identify the instruction involved and zero or more operands, each of which may be more than one byte long, that encodes the parameters the opcode requires.
Set of Registers
For the execution of the byte code, Java virtual machine use a set registers which is very similar to the registers given inside a real computer system. Java virtual machine use registers for performing three major tasks: keeping the machine's state, affecting the operation of virtual machine and updating after each bytes-code is executed.
There are mainly four types of registers given for Java virtual machine. These registers are basically 32-bit wide.
Since Java virtual machine is completely stack based, it does not use any registers (pc, optop, frame and vars) for passing or receiving any type of arguments.
The Stack
Stack plays an important role in the working of Java virtual machine. A Java stack frame is very similar to the stack frame used for a conventional programming language-it holds the state for a single method call. The role of stack in Java virtual machine is to supply parameters to bytecodes and methods, and to receive result back from them.
To understand what has been given for the stack, the above example can be considered once again. In the program JPS2.java method public void paint(Graphics g)
is given. This method accepts object of Graphics
class.
public void paint(Graphics g) { g.setColor(Color.blue); g.drawString(result,120,120); }
The byte code for the above method is:
public void paint(java.awt.Graphics); Code: 0: aload_1 1: getstatic #5; //Field java/awt/Color.blue:Ljava/awt/ Color; 4: invokevirtual #36; //Method java/awt/Graphics. setColor:(Ljava/awt/Color;)V 7: aload_1 8: aload_0 9: getfield #3; //Field result: Ljava/lang/String; 12: bipush 120 14: bipush 120 16: invokevirtual #37; //Method java/ awt/Graphics.drawString:(Ljava/lang/String;II)V 19: return }
Explanation: In the bytecode given above for paint method, aload_1
loads object reference from the local variable. Local variable in the current Java frame must contain a return address or reference to an object (Object g of class Graphics
). Line-2 shows a getstatic field from class. The general form for getstatic is:
getstatic ... . . , =>..., value-word1, value-word2
It is used to construct an index into the constant pool of the current class and the constant pool item will be a field reference to a static field of a class.
1: getstatic #5; // Field java/awt/Color.blue:Ljava/awt/Color;
In the above getstatic
field construct an index into the constant pool for the Color
class. The constant pool item with nothing but the Color.blue will be a field reference to a static field of a class Color
. The value of that field (Color.blue) is placed on the top of the stack. The first stack picture is for 32-bit wide and the second will be for 64-bit. The noticeable point here is if the specified field is not a static field, an IncompatibleClassChangeError is thrown by the system.
Now, the next line of the bytecode is for invokevirtual, which is used to invoke an instance method based on runtime type. The general code for invokevirtual is:
invokevirtual ......, handle, [arg1][arg2... .]......=>......
In the program JPS2.java, invokevirtual has been used to invoke the instance method for paint method.
4: invokevirtual #36; //Method java/awt/Graphics.setColor:(Ljava/ awt/Color;)V
The operand stack must maintain a reference/handle to an object (object g for Graphics
class) and some number of arguments. It use an index into the constant pool of the current class. Item at some particular index in the constant pool contains the complete method signature. The reason why the constant pool contains the method signature is that, ivokevirtual manages a pointer to the object which has been used to invoke the method table is to be retrieved from the object reference. The method signature is then verified from the method table. Method signature is guaranteed to get an exact match for one of the method signatures in the table. If value of handle is null, it throws a NullPointerException
. And if during method invocation a stack overflow is found, a StackOverflowError
is thrown. The role of getfield
is to fetch field from object. There is a handle which must be a reference to an object. bipush
pushes one byte signed integer, as shown in the above bytecode at line-12 and line-14.
12: bipush 120 14: bipush 120
The value then expanded to an int
and pushed onto the operand stack. The method return has used to return
from the method. That is after getting return Java interpreter returns control to its caller. The value is pushed onto the operand stack of the previous execution environment.
The Garbage Collected Heap
The technique through which a program can obtain space in the RAM during the execution of the program and not during compilation is called dynamic memory allocation. In this method, space for the variables (array, strings, etc.) is allocated from a free memory region which is known as heap. This area is not fixed in nature and keeps changing as the memory is allocated and de-allocated from this region. The entire runtime view of memory for a program is shown in Figure 24.5.
The heap is often assigned a large, fixed sized when the Java runtime system is started, but on systems that support virtual memory, it can grow according to the requirement, in an unbounded manner. Since it is well known that Java supports the concepts of garbage collection to collect the object automatically there is no need de-allocate the memory manually from programmers side.
Area for Storing Methods
Java virtual machine supports basically two different areas for storing purposes. The first one is called as Method area and second Constant pool.
Method area: It is very similar to the compiled code area of conventional programming language environment. It keeps the bytecodes used to implement almost all the methods used for Java application development by Java system.
Constant pool: Constant pool is basically given for classes used in the Java system. Since, it is well known that heap is a part of memory from which newly created instance are allocated, each class in the heap has a constant pool attached to it. Constant pool is usually created by javac at the compile time. These constants encode all the names like variables and methods used by any method in a class.
24.3 VIRTUAL MACHINE ERRORS
When any Java program is compiled and interpreted, most of the time problem is faced in loading, linking and initialization of the program ('.bc' or '.class') with virtual machine. A Java virtual machine throws an object that is an instance of a subclass of the class VirtualMachineError
when an internal error or resource limitation prevents it from implementing the semantics of the Java language. The Java virtual machine specification cannot predict where resource limitations or internal errors may be encountered
and does not mandate precisely when they can be reported. Thus, any of the virtual machine errors listed as subclasses of VirtualMachineError
may be thrown at any time during the operation of the Java virtual machine.
24.4 INSTRUCTION SET FOR VIRTUAL MACHINE
Java virtual machine instructions are represented in this chapter by entries of the form shown in Table 24.1.
Operation | Description |
Format | |
Forms | mnemonic = opcode |
Stack | ......., value1, value2 => |
......., vlaue3 |
|
Description | A longer description detailing constraints on operand stack contents or constant pool entries, the operation performed, the type of the result, and so on. |
Linking Exceptions | If any linking exception is thrown by the execution of this instruction, they are set off one to a line in a way that they must be thrown. |
Runtime Exceptions | If any runtime exceptions can be thrown by the execution of an instruction, they are set off one to a line in a way that they must be thrown. Other than the linking and runtime exceptions, if any, listed for an instruction, the instruction must not throw any runtime exceptions except for instances of VirtualMachineError or its subclasses. |
Notes | Comments not strictly part of the specification of an instruction are set aside as note at the end of the description. |
24.5 INVOKING METHODS USING VIRTUAL MACHINE
The normal method invocation for a Java instance method dispatches on the runtime type of the object (they are virtual, in C++ terms). Such an invocation is implemented using the invokevirtual instruction, which takes as its argument an index to a constant pool entry giving the fully qualified name of the class type of the object, the name of the method to invoke, and that method's descriptor. To invoke the area_rectangle method, defined as an instance method, the code can be written as shown below:
Now, the complete bytecode is given for the program JPS3.java.
Explanation: To know the method invocation, the detail of bytecode is first looked into for the method which is shown below:
static int area150n100(); Code: 0: sipush 150 3: bipush 100 5: invokestatic #15; //Method area_rectangle:(II)I 8: ireturn
sipush is given as sipush 100
pushes two byte signed integer where byte1 and byte 2 are combined into a signed 16-bit value. Later on, this value is expanded to a certain extent and pushed onto the stack. bipush
is also given to push the data element but it pushes one byte signed integer. This value is expanded to an int and pushed onto the operand stack. The general signature for sipush and bipush is:
sipush ............ ==> ............, value bipush ............ ==> ............, value
The next statement of the bytecode for the area15n10()
is:
5: invokestatic #15; //Method area_rectangle:(II)I
The byte1 and byte2 are available in the operand stack. These numbers work as arguments. Both the byte1 and byte2 are used to construct and index into the constant pool of the current class. The item which is in the constant pool at a certain index keeps the signature for the method and class. The general form for the invokestatic is:
invokestatic ….. ,[a1, [a2,… .]],...... .=> ...... .
First method invocation starts by pushing the reference of the current instance onto the stack. Then the values are pushed into the stack using sipush
and bipush
statement. When the frame for the area_rectangle
method is created the arguments passed to the method area_rectangle (150, 100)
becomes the initial values of the new frame's local variables. Finally, area_rectangle
is invoked using invokestatic. When area_rectangle
returns the value, its int value is then pushed onto the stack. The return value is thus put in place to be immediately returned to the invoker of int area150n100()
.
The last statement of the bytecode for the method int area150n100()
is ireturn
instruction. The ireturn
is used for the value to be pushed onto the stack of the previous execution environment. The general form for ireturn is given here:
ireturn ........., value => [empty]
The Java virtual machine provides distinct return instructions for many of its numeric and reference
data types, as well as a return
instruction for methods with no return value. The same set of return instructions is used for all varieties of method invocations. The various types of return instruction with their general form used in bytecode to return from method are listed below:
(a) ireturn (General form: ireturn …………, value => [empty])
(b) lreturn (General form: lreturn …………, value-word1, value-word2 =>[empty])
(c) freturn (General form: freturn …………, value => [empty])
(d) dreturn (General form: dreturn …………, value-word1, value-word2 => [empty])
(e) areturn (General form: areturn …………, value => [empty])
24.6 CLASS INSTANCE AND VIRTUAL MACHINE
Java virtual machine class instances are created using the Java virtual machine's new
instruction. Once the class instance and its instance variables have been created, and those of the class and all of its superclasses have been initialized to their default values, an instance initialization method of the new class instance (<init>) is invoked. (Recall that at the level of the Java virtual machine, a constructor appears as a method with the special compiler-supplied name <init>. This special method is known as the instance initialization method. Multiple instance initialization methods, corresponding to multiple constructors, may exist for a given class.) For example:
From the byte code given above, it can be seen that the Java class demo_class_vm
starts with the new instruction which is basically created by Java virtual machine.
Class instances are passed and returned (as reference
types) very much like numeric values, although type reference
has its own complement of instructions:
Becomes like the below given code:
The method given in the above program JPS7.java: silly(JPS7 o)
The fields of a class instance (instance variables) are accessed using the getfield
and putfield
instructions. If i is an instance variable of type int
, the methods setIt
and getIt
are defined as:
void setIt(int value) { i = value; } int getIt() { return i; } Method void setIt(int) 0 aload_0 1 iload_1 2 putfield #4 // Field Example.i I 5 return Method int getIt() 0 aload_0 1 getfield #4 // Field Example.i I 4 ireturn
As with the operands of method invocation instructions, the operands of the putfield
and getfield
instructions (the constant pool index #4) are not the offsets of the fields in the class instance. The Java compiler generates symbolic references to the fields of an instance, which are stored in the constant pool. Those constant pool items are resolved at runtime to determine the actual field offset.
Basically getfield
and putfield
are used for manipulating object fields. The getfield
fetches field object. The constant pool item will be a field reference to a class name and a field name. The general form for getfield is given as:
getfield ............,handle => ............, value getfield ............,handle => ............,value-word1, value-word2
Here, handle must be reference to an object. The value at offset into the object referenced by handle replaces handle on the top of the stack. If the specified field is a static field, an IncompatibleClassChangeError is thrown.
The putfield
is also used for manipulating object fields. This instruction sets field in object. The constant pool item is a field reference to a class name and a field name. The general form for putfield is:
putfield ............, handle, value => ............ Putfield ............, handle, value-word1, value-word2 => ............
If handle is null, a NullPointerException is thrown and if the specified field is a static field, an IncompatibleClassChangeError is thrown.
24.7 ARRAY AND VIRTUAL MACHINE
Arrays are also served as an object for Java virtual machine. To create an array of a numeric type the newarray
instruction is used in the bytecode.
The above code might be compiled to
Explanation: The above bytecode is given for the Java application program where array has been used. At line 0 of public static void main(java.lang.String[]);
iconst_5 is given which is a pushing instruction, used to push the five integer values onto the stack. There are six of these bytecodes one for each of the integers 0-5 (icont_0, iconst_1, iconst_2, inconst_2, iconst_3, iconst_4 and iconst_5) given by line 5, 12, 13, 16, 17, 20 and 21. The general form iconst is given below:
iconst_ ........, => ........,
The next instruction given in the above bytecode is nothing but the instruction used for creating an array of numeric type. The general form of this instruction is:
newarray ........, size => result
The newarray
instruction is given to manage the array. It is used to allocate new array. Its size must be an int. It represents the number of elements in the new array. The newarray instruction is an attempt to allocate a new array of the indicated type, which is capable of holding size elements. If size is less than zero, a NegativeArraySizeException
is thrown and if there is not enough memory to allocate the array, an OutOfMemoryError
is thrown. The instruction dup is give at line-3 used for stack operation. The dup
is used to duplicate the top word on the stack. The general form for dup instruction is:
dup ....., any => ........., any, any
Now the next instruction given in the above bytecode for JPS5 will be discussed, which is iastore
given at line-6. The general form of iastore is given below:
iastore ...... ., array, index, value => ......
The iastore
stores the value into the array. Array must be an array of int, index must be an integer. If array is null, a NullPointerException
is thrown and if index is not within the bounds of array, an ArrayIndexOutOfBoundsException
is thrown.
The next instruction discussed here is astore
, given at line-23 in the bytecode shown above.
23: astore_1
The astore
stores the object reference into the local variable. It uses a handle. Handle must be a return address or a reference to an object. The general form for the astore
instruction is given as:
astore_<A> ......., handle => ......
There are four types of these bytecodes, one for each of the integers starting from 0 to 3 as:
astore_0, astore_1, astore_2 and astore_3 .
Now, the working of istore
given at line-25 will be discussed. The istore
is used to store stack values into local variables.
25: istore_2
In the instruction istore 'i'
is given for integer. That is the reason istore
instruction is used to store int into the local variable. The general signature for the instruction is given as:
istore ........., value => .........
The next new instruction given in the bytecode is iload given at line-26
26: iload_2
The iload
instruction is nothing but the instruction given for the Java virtual machine to load the local variables onto the stack. The signature for iload instruction is:
iload_ ...... . . => ......, value
The role of iload
is to load int from local variable onto the operand stack. The local variable (<i>load_2
shown in the byte code) in the current Java frame must contain an int. There are four different flavours of iload
instruction, one for each of the integer starting from 0 to 3: iload_0
, iload_1
, iload_2
and iload_3
.
Now a bit about the aload
instruction will be discussed. The aload
instruction is shown in the above bytecode at line-27 as:
27: aload_1
There are mainly two types of aload
instructions. The signature of both the aload instructions is given below:
aload ...... => ......, value
It is used to load object reference from local variable.
aload_<A> ...... . => ..... . , value
It is used to load object reference from local variable. Here local variable <A> in the current Java frame must contain a return address or reference to an object. There are four different bytecodes for aload_<A>
, one for each of the integer 0-3: aload_0
, aload_1
, aload_2
and aload_3
.
The next instruction given in the bytecode file JPS5.bc
is if_icmpge
which is nothing but used for transferring control. The instruction if_icmpge
is given at line-29 as shown below:
29: if_icmpge 65
For the description of if_icmpge
instruction, the signature of the instruction is looked into which is given as:
if_icmpge ..... . . , value1, value2 => ......
Here for the instruction if_icmpge
execution proceeds at that offset where value<rel>0
is true in the first set of bytecodes Table 24.2, value1<rel>value2
is true in the second set, or value is null or not null in the third; byte1 and byte2 are used to construct a signed 16-bit offset from the pc (register). Here <rel> is nothing but one of eq, ne, lt, gt, le, and ge which represents the following:
Bytecode for if_icmpge | Meaning |
eq |
Equal |
ne |
Not equal |
lt |
Less than |
gt |
Greater than |
le |
Less than or equal |
ge |
Greater than or equal |
Now getstatic
instruction can be discussed which is used for manipulating object fields. The getstatic field is shown in the above code at line-32
32: getstatic #2; //Field java/lang/System.out: Ljava/io/PrintStream;
The instruction getstatic
is given to get static field from class. There are two flavours of getstatic
instruction. The general form of both the getstatic type is given below:
getstatic ........ . , => ............, value getstatic ........ . , => ............, value-word1, value-word2
For getstatic
instruction byte1 and byte2 are used to construct an index into the constant pool of the current class. The constant pool item will be field reference to a static field of a class. The value of that field is placed on the top of the operand stack. Here it is important to note that the first stack picture is for 32-bit and the second for 64-bit-wide fields.
The next instruction to be focussed is new instruction. In the above bytecode new is used at line-35 as shown below:
35: new #3; //class java/lang/StringBuilder
The new instruction is mainly used to create new object. The general form for new instruction is given below:
new ........ . => …..,handle
Byte1 and byte2 are used to construct an index into the constant pool of the current class. The item at that index must be a class name that can be resolved to a class pointer, class.
The iaload
instruction is the next instruction which will be discussed now. It is given in the above bytecode at line-44.
44: iaload
The signature for the iaload instruction is given below:
iaload ........, array, index => …., value
The iaload
instruction is used to load <type> from array. For the array, index must be integer type. The <type> value at position number index in array is retrieved and pushed onto the top of the stack.
The ldc
instruction is used to push the item from the constant pool. In the byte code ldc
instruction has been given at line-48
48: ldc #6; //String
The iinc
instruction is given to increment local variable by constant. The iinc
instruction is given at line-59 in the above bytecode given for JPS5.bc
59: iinc 2, 1
Value of iinc
instruction is incremented by the value byte2, where byte2 is treated as a signed 8-bit quantity.
The last instruction of the above bytecode is goto
instruction, which is given at line-62 as given below:
62: goto 26
There are two versions of goto statement: goto -no change
and goto -no
change.
The goto
instruction is also used for transferring control. Byte1 and byte2 are used to construct a signed 16-bit/32-bit offset. For goto
statement, execution starts at that particular offset from the register pc.
24.8 SWITCH STATEMENTS AND VIRTUAL MACHINE
There are two different types of instruction to compile switch statement in Java: tableswitch instruction and lookupswitch instruction.
To see the working of both the instructions given for handling switch statement in Java an example is given below.
The bytecode for the above program can be generated:
Explanation: The tableswitch
instruction is used when the cases of the switch
can be efficiently represented as indices into a table of target offsets. The important point for tableswitch instruction is that it operates only on integer data. The tableswitch instruction is efficient in terms of space complexity. In the above bytecode tableswitch instruction is given at line-25 as shown below:
25: tableswitch{ //0 to 2 0: 52; 1: 63; 2: 74; default: 85}
To understand the working of tableswitch instruction, the general form given for the instruction can be considered:
tableswitch ....... . .index => …..
Only three cases are given under switch
statement in the program. And the cases given in switch
statement are case 0, case 1 and case 2; therefore the index value will start from 0 to 2 as shown in the bytecode. The tableswitch is a variable-length bytecode. Immediately after the tableswitch opcode, zero to three 0 bytes are inserted as a padding so that the next byte starts at an address that is a multiple of 4. After the padding, a series of signed 4-byte quantities will come into picture which is nothing but default-offset, low, high, and then high-low+1. These offsets are treated as a 0-based jump table. The important thing behind the index is, if the index is less than low or if it is greater than high, default-offset is added to the pc (register).
In the above section, a lot has been discussed for tableswitch instruction. Now, lookupswitch
instruction will be discussed which is also used for switch
statement. It is a variable-length bytecode. To understand the working of lookupswitch
the example JPS7.java is given below:
Now, the program will be compiled to get the .class file (JPS7.class) which contains the byte code. Also javap will be used to get the bytecode for the same file.
The bytecode file for JPS7.java is shown below:
Explanation: The lookupswitch
instruction is used when the cases of the switch
statement is not efficiently represented as indices into a table of target offsets. The important point for lookupswitch
instruction is that it also operates only on integer data like tableswitch opcode. The bytecode for lookupswitch opcode is given in the above bytecode at line-25.
25: lookupswitch{ //3 -5: 60; 0: 71; 5: 82; default: 93 }
The general form given for lookupswitch opcode is shown as:
lookupswitch ........, key => …..
If the general signature is compared with the lookupswitch
instruction given in the bytecode, it can be said that the value of key is 3. Immediately after the lookupswitch
opcode, zero to three 0-bytes is inserted as padding so that the next byte starts that is a multiple of 4. And immediately, after the padding is a series of pairs of signed 4-byte quantities. The first pair is special, because it contains the default offset and the number of pairs that follow. The special thing for lookupswitch
is that the key on the operand stack must be an int. This key is basically compared with each of the matches. If it is equal to one of them, the corresponding offset is added to the pc register. And if the key does not match any of the matches, the default offset is added to the pc. Even though, the lookupswitch
instruction must search its keys for a match rather than simply perform a bounds check and index into a table like tableswitch
. Thus, a tableswitch
instruction is probably more efficient than a lookupswitch
where space considerations permit a choice.
24.9 THROWING AND HANDLING EXCEPTIONS, AND VIRTUAL MACHINE
This section reveals the inner working of exception handling mechanism that Java supports. Several exception handling mechanisms like try, catch
and throw
are discussed. Therefore to understand the working of exception handling mechanism, an example can be given here.
Exceptions are thrown from Java programs using the throw
keyword. Its compilation is simple:
The bytecode for the above Java application program is given below:
Explanation: For digging the matter deep about the working of exception handling mechanism, there has to have the detailed ideas about the opcode given in the above bytecode file JPS11.bc
. Hence, discussion will begin with if_icmpgt
instruction given at line-9 for public static void main(java.lang. String[]);
9: if_icmpgt 72
The opcode if_icmpgt
is nothing but the instruction for transfer control. The general signature for if_icmpgt
is given as:
if_icmpgt ........, value1, value2 => ........ .
It is used to jump if one integer is greater than another. In the above shown bytecode first 10 is pushed onto the stack by bipush
opcode at line-0 and stored by using istore_1
as shown at line-1. The value 10 has been assigned in the variable num
which is of integer type. Then again in for
loop the value 10 in num
is once again assigned ; for this purpose once again bipush
and istore
instruction has been used at line-3 and line-5, respectively. After that the instruction iload_1
is given to load the value 10 in the operand stack. Again bipush
is given to push the value 30 onto the stack as boundary condition for
the for loop; that is if the value will be less than or equal to 30, for
loop will work otherwise control will move out from the loop. To achieve this condition (if value of num is more than 30) in the next line if_icmpgt
is given. The role of if_icmpgt
is just to jump if one integer is greater than another. Form the bytecode we can see that at line-9, if_icmgt
opcode is given, which has the value 72 and at line-72 return
statement is given. The next instruction discussed here is if_icmpne
given at line-15.
15: if_icmpne 26
This instruction is also a transfer control instruction used to transfer the control if two integers are not equal. The working of if_icmpne
is that it first pops the top two values of integer type from the operand stack and then compares the values. If the two integers are not equal, execution branches to the address (pc: program counter). But if the integers are equal, execution continues at the next instruction. The general signature for if_icmpne
opcode is:
if_icmpne ........, value1, value2 => ............
The first condition (if-statement) given in the try block of JPS11.java is:
if (num == 20) throw new demo1();
Since, initially value of num is 10 and in the if-statement
the condition has been given for checking the equality of num with 20 which is not correct, therefore it will throw an exception. Diagrammatically it can be represented as:
value1 = 10 (num) value2 = 20
Since num is not equal to 20 exception is obtained. But if the exception is not obtained, the bytecode given below will execute:
18: new #2; //class demo1 21: dup 22: invokespecial #3; //Method demo1."<init>":()V 25: athrow
The new opcode is given to create new object for the class demo1. The role of dup opcode is to duplicate the top word given on the stack. Invokespecial is a method invocation opcode which is used to invoke method (demo1 for the program JPS11.java) belonging to a specific class. The athrow opcode is an exception handling opcode. The signature of athrow opcode is:
athrow ........handle => [undefined]
Rest of the portion is self-explanatory.
24.10 JAVA BASE API
Currently the Java base API is defined to be the Java applet API, described in the next sections. Over time, as the platform develops, this base will grow, as some of the standard extension API migrate into the Java base API. The Java base API is also known as the Java core API.
24.10.1 Java Applet API
The Java applet API, also known as the Java base API, defines the basic building blocks for creating fully functional Java-powered applets and applications. It includes all the classes in the Java package: java.lang, java.util, java.io, java.net, java.awt and java.applet.
24.11 JAVA STANDARD EXTENSION API
In this section, the Java standard extension API is described. These extensions are 'standard' in that they form a published, uniform, open API that anyone can implement. Once defined, they can be added to maintain backward compatibility, not changed in a way that calls to them would fail. Over time, new extensions will be added. In addition, some of these extensions will migrate into the Java base API. The current plan for this migration is shown in the Table 24.3.
Java API | |
Migrate to Java Base API | Remain as Java Standard Extension |
Java 2D | Java 3D |
Audio | Video, MIDI |
Jaav Medai Framework | Java Share |
Java Animation | Java Telephony |
Java Enterprise | Java Server |
Java Commerce | Java Management |
Java Security |
An implementation should do whatever is appropriate for the platform it runs on, within its hardware constraints. For example, desktop operating systems that have access to speaker will produce audio; however, a mainframe or network operating system that has no speaker is permitted to do the equivalent of a no-op or some other well-defined behaviour, such as throwing an exception.
24.11.1 Java Security API
The Java security API is a new Java core API, built around the java.security
package (and its subpackages). This first release includes primarily cryptography functionality, which can be incorporated into Java-based applications. Future releases of this API will include more primitives supporting system security and secure distributed computing.
The Java security API is a framework for developers to easily and securely include security functionality in their applets and applications. This functionality includes cryptography, with digital signatures, encryption and authentication.
The cryptography framework in the Java security API is designed so that a new algorithm can be added later on without much difficulty and can be utilized in the same fashion as existing algorithms. For example, although DSA is the only built-in digital signature algorithm in this release, the framework can easily accommodate another algorithm such as RSA.
APIs for data encryption and other functionalities, together with their implementations, will be released separately in a 'Java Cryptography Extension' (JCE) as an add-on package to JDK. These APIs include block and stream cipher, symmetric and asymmetric encryption, and support for multiple modes of operation and multiple encryption.
Java security includes an abstract layer that applications can call. This layer, in turn, makes calls to Java security packages that implement the actual cryptography. This allows third-party developers specializing in providing cryptographic functionality to write packages for Java security. Java security also includes system support for key management, including a secure database, certificate facility, and so on.
This architecture provides for replaceable, upgradeable security. Whenever a strong algorithm or a faster implementation becomes available, modules can be replaced in the platform, in a manner completely transparent to applications.
24.11.2 Java Media API
To support various interactive media on and off the Web Java supports the Java media API. The Java media API mainly defines the multimedia classes given in Java. It is highly extensible, which is composed of various different components. The component of Java media APIs includes audio, video, 2D and 3D animation, telephony, Java speech and Java collaboration. The main focus of Java media API is to provide interfaces to Java programmers to use a wide range of media types within their applications and applets.
The components of the Java media APIs are as follow:
1. Java 2D API : It mainly includes line art, images, color, transforms and compositing. It provides an abstract imaging model which extends the functionality of 1.02 AWT package. Java 2D API also provides an extension mechanism to support various arrays of different presentation devices, image formats, color spaces and encoding mechanism.
2. Java Media Framework (JMF) API: It specifies a unified architecture, messaging protocol and programming interface for media players, capturing and conferencing. It mainly handles time critical media, such as audio, video and MIDI where synchronization is required. Java media framework will be published as three APIs.
Java media player: The Java media player will be published first. It is the API used for synchronization, controlling, processing and presenting of compressed streaming and stored timed media, which includes video and audio.
Java media capture: It is used to capture the Web pages.
Java media conference: Especially for conference Web pages and API specification are not yet published.
Java collaboration API: Provides interactive two-way, multiparty communication over a variety of dedicated networks. There will be two versions of Java collaboration.
Ver1: Given for sharing of collaboration-aware applications.
Ver2: Given for sharing of collaboration-unaware applications.
Java telephony API: It mainly works to integrates telephones with computers. Java telephony gives the idea of 'how to control the phone calls' . It provides basic functionality for first-party and third-party call control.
Java speech: It provides Java based speech recognition and speech synthesis system.
Java animation API : It provides Java based system for motion and transformation of 2D objects.
It uses Java media framework for synchronization, composition and timing.
Java 3D API: It has been used specially for 3D objects. To handle 3D object, Java 3D provides an abstract, interactive imaging model. The 3D API is closely integrated with audio, video, MIDI and animation area.
24.11.3 Java Enterprise API
Java enterprise APIs are mainly given to support connectivity to enterprise databases. There are various types of database architecture like centralized, client-server, multiprocessor and distributed. With the help of Java enterprise APIs, corporate developers are building distributed client/server applets and applications in Java that run on any operating system or hardware platform in the enterprise. There are currently three groups for connectivity: JDBC (Java database connectivity), interface definition language and remote method invocation.
JDBC: JDBC is Java database connectivity, a standard SQL database access interface, which is used for providing access to a wide range of relational databases. JDBC is also used to provide a common base on which higher level tools and interfaces can be developed.
Interface Definition Language (IDL): It is developed to the OMG interface definition language specification. It is a language-neutral way to specify and interface between an object and its client on different platform. Java interface definition language (IDL) is implemented completely in Java. Mainly Java IDL components are used to provide mapping of its method, packages, etc., to IDL operations and features.
Remote Method Invocation: It is given for invocation between peers, or between client and server. RMI performed, serves its purpose when applications at both the ends of the invocation are written in Java.
24.11.4 Java Commerce API
It will bring a methodology for secure purchasing and financial management on Web. The initial component of the Java commerce API is the Java wallet, which defines and implements a client-side framework for credit card, and electronic cash transactions. For secure purchasing and financial management, Java wallet keeps the information about the shopper, payment instruction and details of transactions. It also uses strong cryptographic services that makes the complement process secure.
24.11.5 Java Server API
Java server API provides a uniform and consistent access to the server and administrative system resources. It is an extensible framework that enables and ease the development of a whole spectrum of Java-powered Internet and Intranet servers. Java serves API its own Java 'servlets' executable program that users upload to run on networks or servers. Servlets are platform-independent, server-side programming. They can reside on the server.
24.11.6 Java Management API
It provides a wide range of extensible Java objects and methods for building applets that can manage an enterprise network over Internets. It is composed of several different components, each associated with an aspect of the total management space. Since Java management API is a collection of Java classes it provides the building blocks for integrated management. The components of Java management APIs are shown in the diagram below:
24.12 THE JAVA API PACKAGE
All the core API packages defined by Java and their functionality are summarized in the Table 24.4.
Package | Description |
java.applet | Provides support for applets construction. |
java.awt | Provides capability of graphical user interfaces. |
java.awt.color | Provides support for color spaces and profiles. |
java.awt.datatransfer | Transfers data to and from the system clipboard. |
java.awt.font | Represent various types of font. |
java.awt.geom | Facilitate working with geometric shapes. |
java.awt.im | Allow input of Chinese, Japanese and Korean characters to text editing components. |
java.awt.dnd | Support for drag-and-drop operations. |
java.awt.event | Handle events. |
java.awt.im.spi | Support for alternative input devices. |
java.awt.image | Process images. |
java.awt.image.rederable | Support rendering-independent images. |
java.awt.print | Provide general print capabilities. |
java.beans | Allows programmer to build software component. |
java.beans.beanscontext | Creates an execution environment for Beans. |
java.io | Provides input and output files. |
java.lang | Provides core functionality. |
java.lang.annotation | Provides support for annotations. |
java.lang.instrument | Gives support for program instrumentation. |
java.lang.management | Provides support for management of the execution environment. |
java.lang.ref | Enables some interaction with the garbage collector. |
java.lang.reflect | Analyzes code at runtime. |
java.math | Handles large integers and decimal numbers. |
java.net | Supports networking. |
java.nio | Top-level package for the NIO classes and encapsulates buffers. |
java.nio.channels | Encapsulates channels, used by the NIO system. |
java.nio.channels.spi | Supports service providers for channels. |
java.nio.charset | Encapsulates character sets. |
java.nio.charset.spi | Supports service providers' character set. |
java.rmi | Provides remote method invocation. |
java.rmi.activation | Activates persistent objects. |
java.rmi.dgc | Manages distributed garbage collection. |
java.rmi.registry | Maps names to remote object references. |
java.rmi.server | Supports remote method invocation. |
java.security | Handles certificates, keys, digests, signatures and other security functions. |
java.security.acl | Manages access control lists. |
java.security.cert | Parses and manages certificates. |
java.security.interfaces | Defines interfaces for DSA (Digital Signature Algorithm) keys. |
java.security.spec | Specifies keys and algorithm parameters. |
java.sql | Communicates with a SQL (Structured Query Language) database. |
java.util | Contains the common utilities. |
java.util.concurrent | Supports the concurrent utilities. |
java.util.jar | Creates and reads JAR files. |
java.util.logging | Supports logging of information relating to user preference. |
java.util.prefs | Encapsulates information relating to user and system preferences. |
java.util.regx | Supports regular expression processing. |
java.util.spi | Supports service providers for the utility classes in java.util. |
java.util.zip | Reads and writes compressed and uncompressed ZIP files. |
24.13 PONDERABLE POINTS
1. The Java platform has two main parts: the Java virtual machine and the Java API.
2. The Java API specifies a set of essential interfaces in a growing number of key areas that developers will use to build their Java-powered applications.
3. Java API basically has two parts: Java base API and Java standard extension API.
4. The Java virtual machine is key to the independence of the underlying operating system and hardware.
5. The Java base API is defined to be the Java applet API.
6. The Java applet API, also known as the Java base API, defines the basic building blocks for creating Java-powered applets.
7. Java applet API includes all the classes in the Java package: java.lang, java.util, java.io, java.net, java.awt and java.applet.
8. The Java security API is a framework for developers to easily and securely include security functionality in their applets.
9. Java security includes an abstract layer that applications can call.
10. The Java media API defines the multimedia classes that support a wide range of rich, interactive media on and off the Web.
11. The Java media API includes audio, video, 2D and 3D animation, telephony and collaboration.
12. Java 2D API provides graphics and imaging capabilities beyond those available with the Java applet API.
13. Java media framework API handles traditional time critical media such as audio, video and MIDI.
14. Java animation API supports 2D animations.
15. Java share API provides the basic abstraction for live, two-way, multi-party communication between objects over a variety of networks and transport protocols.
16. Java 3D API provides high-performance, interactive, 3D graphics support.
17. Java enterprise API supports three groups for connectivity: JDBC (Java database connectivity), interface definition language and remote method invocation.
18. Java server API is an extensible framework that enables and eases the development of a whole spectrum of Java-powered Internet and intranet server.
19. Java management API is a collection of Java classes that provides the building blocks for integrated management.
REVIEW QUESTIONS
1. What is the Java platform?
2. Explain the term Java base platform and embedded Java platform.
3. Explain the term Java API. Also explain Java base API and the Java standard extension API.
4. Explain the functionality of Java security API with example.
5. Why do we use Java media API? Also explain the components of the Java APIs.
6. Explain the term Java enterprise API.
7. What do you understand by Java commerce API? Also explain the functionality of the Java wallet.
8. Explain the working of Java server API.
9. Give the functionality of the components of Java management APIs.
10. Describe the virtual machine in detail.
11. What do you understand by instruction set for virtual machine.
12. Give the procedure for invoking method using virtual machine.
13. What is class instance?
14. What is cryptographic package provider used for API?
15. Give the detailed procedure for debugging in API environment.
16. Explain the term 'remote debugging' for API.
17. Explain Java debugger for API environment.
18. Explain the Java classes used for debugging APIs. Also explain the data types associated with Java debugging API.
Multiple Choice Questions
1. Java platform has the part
(a) Java virtual machine
(b) Java API
(c) (a) and (b)
(d) Noneofthe above
2. The virtual machine defines a machine independent format for binary files which is called as:
(a) .exe file
(b) .class file
(c) .javafile
(d) .datfile
3. To see the bytecode of Java's program we will use
(a) javac -c filename>filename.bc
(b) javah -c filename>filename.bc
(c) javap -c filename>filename.bc
(d) java -c filename>filename.bc
4. Any of the virtual machine errors listed as sub classes of ___________, may be thrown at any time during the operation of the Java virtual machine.
(a) VirtualMachineError
(b) MachineError
(c) MachineExecutionError
(d) None of the above
5. In Java, method invocation is done by
(a) invokevirtual instruction
(b) bipushvirtual instruction
(c) bipush instruction
(d) None of the above
6. For the method
int sum10and20() { return addTwovalue(10, 20); }
This compiles
0 aload_0 1 bipush 10 3 bipush 20 8 ireturn
Here ireturn
is used to
(a) just to return the value by default
(b) take int value by addTwovalue
(c) return value to sum
(d) none of the above
7. The invokespecial
instruction must be used to
(a) invoke variables
(b) invoke stack storage area
(c) invoke instance initialization <init> method
(d) none of the above
8. Java virtual machine class instances are created using the Java virtual machine by
(a) Using invokespecial instruction
(b) Using <init> instruction
(c) Using aload_0 instruction
(d) Using new instruction
9. Which of the following is the method of DebuggerCallBack class?
(a) threadDeathEvent()
(b) void threadDeathEvent(int a)
(c) public void threadDeathEvent (int a)
(d) public threadDeathEvent()
10. For getting the code position when we are using RemoteStackFrame we will use
(a) getRemoteClass()
(b) getLocalVariable()
(c) getpc()
(d) None of the above
KEY FOR MULTIPLE CHOICE QUESTIONS
1. c
2. b
3. c
4. a
5. a
6. b
7. c
8. d
9. a
10. c
3.144.96.105