Chapter 2 Java Programming
What is Java?
Java is a recently developed concurrent, class-based, object oriented programming language that
is:
-
Simple. It is similar to C++, but with most of the more complex features of C and C++
removed. Java does not provide:
-
Object-oriented. Java provides the basic object technology of C++ with some
enhancements and some deletions.
-
Architecture neutral. Java source code is compiled into an architecture independent
object code. The object code is interpreted by a Java runtime system.
-
Portable. Java implements additional portability standards. For example, ints are always 32-bit, 2's-complemented integers. User interfaces are built through an abstract
window system that is readily implemented in Solaris and other operating environments.
-
Distributed. Java contains extensive TCP/IP networking facilities. Library
routines support protocols such as Hypertext transfer
Protocol (HTTP) and file transfer protocol (FTP).
-
Robust. Both the Java compiler and the Java interpreter
provide extensive error checking. Java manages all dynamic memory for you,
checks array bounds, and checks other exceptions.
-
Secure. features of C and C++ that often result
in illegal memory accesses are not in the Java language. The interpreter also
applies several tests to the compiled code to check for illegal code. After
these tests, the compiled code causes no operand stack over- or underflows,
performs no illegal data conversions, performs only legal object field accesses,
and the types of all opcode parameters are legal.
-
High performance. Compilation of programs to an
architecture independent machine-like language, results in a small efficient
interpreter of Java programs. In the future, the Java environment will also
assemble the Java byte code into native machine code at run time.
-
Multithreaded. Multithreading is built into the
Java language. It can improve interactive performance by allowing operations,
such as loading an image, to be performed while continuing to process user
actions.
-
Dynamic. Java does not link invoked modules until
run time.
The Java Programming Environment
Programming in Java is supported in Solaris JavaVM by your favorite
text editor, make(1S),
and by:
|
javac
|
Java compiler. Translates Java source code files (name.java) into byte code files (name.class) that
can be processed by the
interpreter (java(1)). Both Java applications and Java
applets are compiled.
|
|
javald
|
Wrapper generator.
Creates
a wrapper that captures the environment needed to compile and run a Java application.
Since the specified paths are not bound until the wrapper is invoked, the
wrapper allows for relocation of the JAVA_HOME and CLASSPATH paths.
|
|
java
|
Java interpreter. May be
invoked as a command to execute a Java application or from a browser via html
code to execute an applet.
|
|
appletviewer
|
Java applet
viewer.
This command displays specified document(s) or resource(s) and runs each applet
referred to by the document(s).
|
|
javap
|
Java class file
disassembler.
Disassembles a javac compiled byte code class file and prints the result to stdout.
|
|
javah
|
C header and stub file generator.
For each class specified, creates a header file, named classname.h, and places it in the current directory.
Also, optionally, produces C source stub files.
|
(For more information on using make(1S) see the chapter "make Utility"
in the Programming Utilities Guide.)
The normal Java environment variables are:
|
Variable
|
Description
|
|
JAVA_HOME
|
Path of the
base directory of the Java software. For example, javac, java,
appletviewer, javap, and javah are all contained in $JAVA_HOME/bin. Does not need to
be set to use Solaris JavaVM.
|
|
CLASSPATH
|
A colon (:)
separated list of paths to directories containing compiled *.class files for use with
applications and applets. Used by javac,
java, javap, and javah. If not set, all Solaris JavaVM executables default
to /usr/java/lib/classes.zip. Does not need to be set to
use Solaris JavaVM.
|
|
PATH
|
The normal executable
search
list can contain $JAVA_HOME/bin.
|
Note -
The JavaVM tools are installed in /usr/java/bin
and symbolic links to each executable are stored in /usr/bin.
This means that nothing needs to be added to a user's PATH
variable to use the newly installed JavaVM package. Also, all Solaris JavaVM
executables default to the path /usr/java/lib/classes.zip
to find the standard Java class library.
The base Java programming environment provides no debugger. A debugger
is included in the optional Java Workshop package.
Java Programs
Java programs are written in two forms: applications and applets.
Java applications are run by invoking the Java interpreter from the
command line and specifying the file containing the compiled application.
Java applets are invoked from a browser. The HTML code interpreted by
the browser names a file containing the compiled applet. This causes the browser
to invoke the Java interpreter which loads and runs the applet.
An Application
Example 2-1 is the
source of an application that simply displays "Hello World" on stdout.
The method accepts arguments in the invocation, but does
nothing with them.
Example 2-1 A Java Application
//
// HelloWorld Application
//
class HelloWorldApp{
public static void main (String args[]) {
System.out.println ("Hello World");
}
}
Note that, like C, the method, or function, to be initially executed
is identified as main. The keyword public
lets the method be run by anyone; static makes main refer to the
class HelloWorldApp and no
other instance of the class; void says that main returns
nothing; and args[] declares an array of type String.
The application is compiled by
$ javac HelloWorldApp.java
It is run by
$ java HelloWorldApp arg1 arg2 ...
An Applet
Example 2-2 is the
source of the applet which is equivalent to the application in Example 2-1.
Example 2-2 A Java Applet
//
// HelloWorld Applet
//
import java.awt.Graphics;
import java.applet.Applet;
public class HelloWorld extends Applet {
public void paint (Graphics g) {
g.drawstring ("Hello World", 25, 25);
}
}
In an applet, all referenced classes must be explicitly imported. The keywords public and void
mean the same as in the application; extends says that
the class HelloWorld inherits from the class Applet.
The applet is compiled by
$ javac HelloWorld.java
The applet is invoked in a browser by HTML code. A minimum HTML page
to run the applet is:
<title>Test</title>
<hr>
<applet code="HelloWorld.class" width=100 height=50>
</applet>
<hr>
javald and Relocatable Applications
Correct execution of many Java applications depends on the values of
the JAVA_HOME, CLASSPATH, and LD_LIBRARY_PATH
environment variables. Because the values of these
environment variables are controlled by each individual user, they can be
set to arbitrary paths, with either path being unusual. Further, it is common
for an application to require an unique value in the CLASSPATH
variable.
javald(1) is a command that generates wrappers for Java applications.
The wrapper can specify the correct paths for any or all of the JAVA_HOME, CLASSPATH, and LD_LIBRARY_PATH environment variables. It does so, with no
effect on the user's
values of these environment variables. And it overrides the user's values
for these environment variables during execution of the Java application.
Further, the wrapper ensures that the specified paths are not bound until
the Java application is actually executed, which maximizes relocatability
of applications.
Java Threads on Solaris
The Java programming language requires that multithreaded programs be supported. All java interpreters
provide a multithreaded programming environment. Many of these interpreters, however, support only a single
processor form of multithreading. Thus, the threads of a Java program, in a conventional Java interpreter
executing on a multiprocessor, do not execute fully concurrently; only one thread actually executes at
a time.
The Solaris Java Virtual Machine interpreter takes full advantage of multiple-processor computing
systems. It does this by using the intrinsic Solaris multithread facilities, which allow multiple threads
of a single process to be scheduled onto multiple CPUs simultaneously. The result is a substantial increase
in the degree of concurrency for a multithreaded Java program when it is run under Solaris JavaVM.
Figure 2-1 roughly illustrates how Java threads operate
under Solaris JavaVM. A complete description of the operation of Solaris threads is in Multithreaded Programming Guide.
Figure 2-1 Java threads on Solaris
Tuning Multithreaded Applications
To take full advantage of Solaris threads, a compute-bound application such as parallelized matrix
multiplication, an application must use a native method to call thr_setconcurrency(3T). This insures that sufficient concurrency resources are available to
the Java application to fully use multiple processors. This is not necessary for most Java applications
and applets. The following code is an example of how to do this.
The first element is the Java application, MPtest.java, that will use MPtest_NativeTSetconc(). This application creates 10 threads, each of which displays an identifying
line and then loops 10,000,000 times to simulate a compute bound activity.
Example 2-3 MPtest.java
import java.applet.*;
import java.io.PrintStream;
import java.io.*;
import java.net.*;
class MPtest {
static native void NativeTSetconc();
static public int THREAD_COUNT = 10;
public static void main (String args[]) {
int i;
// set concurrency on Solaris sets it to sysconf(_SC_NPROCESSORS_ONLN);
NativeTSetconc();
// start threads
client_thread clients[] = new client_thread[ THREAD_COUNT ];
for ( i = 0; i < THREAD_COUNT; ++i ){
clients[i] = new client_thread(i, System.out);
clients[i].start();
}
}
static { System.loadLibrary("NativeThreads"); }
}
class client_thread extends Thread {
PrintStream out;
public int LOOP_COUNT = 10000000;
client_thread(int num, PrintStream out){
super( "Client Thread" + Integer.toString( num ) );
this.out = out;
out.println("Thread " + num);
}
public void run () {
for( int i = 0; i < this.LOOP_COUNT ; ++i; ) {
;
}
}
}
|
The second element is the C stub file, MPtest.c, that is generated from MPtest.java by the utility javah(1). Do this by typing
% javah -stubs MPtest.java
The third element is the C header file, MPtest.h, that is also generated from MPtest.java by the utility javah(1). Do this by typing
% javah MPtest.java
The fourth element is the C function, NativeThreads.c, which performs the call
to the C-library interface.
Example 2-4 NativeThreads.c
#include <thread.h>
#include <unistd.h>
void MPtest_NativeTSetconc(void *this) {
thr_setconcurrency(sysconf(_SC_NPROCESSORS_ONLN));
}
Finally, combining the four files into the Java application, MPtest.class, is
most easily done with a make file such as
Example 2-5 MPtest make file
# Make has to be done in two stages:
# first do "make MPtest"
# Then create NativeThreads.c to incorporate the native call
# to "thr_setconcurrency(sysconf(_SC_NPROCESSORS_ONLN))
# and then do "make lib".
# After this, you should be able to run "java MPtest" with
# LD_LIBRARY_PATH and CLASSPATH set to "."
JH_INC1=/usr/java/include
JH_INC2=/usr/java/include/solaris
CLASSPATH=.; export CLASSPATH
MPtest:
javac MPtest.java
(CLASSPATH=.; export CLASSPATH; javah MPtest)
(CLASSPATH=.; export CLASSPATH; javah -stubs MPtest)
cc -G -I${JH_INC1} -I${JH_INC2} MPtest.c NativeThreads.c \
-o libNativeThreads.so
clean:
rm -rf *.class MPtest.c MPtest.o libNativeThreads.so \
NativeThreads.o *.h
|
To Do More With Java
The Java WorkShop is an unbundled package from SunSoft DevPro. JWS is implemented in Java and uses
its own Java interpreter. Java WorkShop consists of eight applications. These are Portfolio Manager, Project
Manager, Source Editor, Build Manager, Source Browser, Debugger, Applet Tester, and Online
Help.
|
Portfolio Manager
|
Creates and customizes portfolios of your Java projects. It manages collections
of objects and applets from which you create new applets and applications.
|
|
Project Manager
|
Sets preferences and directories for your project. Instead of you memorizing
paths to components, the project manager organizes and saves the locations
and preferences for you.
|
|
Source Editor
|
A point-and-click
tool for creating and editing source
code. Other components of Java WorkShop invoke the Source Editor at many points
in the creation, compiling, and debugging process.
|
|
Build Manager
|
Compiles Java source
code to Java byte-code and locates errors in the source. In launching the
Source Editor, the Build Manager links you to the editor in the source code,
which lets you correct an decompile very quickly.
|
|
Source Browser
|
Displays a tree diagram
that shows the class inheritance of all the objects in your project. It also
lists all constructor and general methods in your project and lets you search
for strings and symbols. The Source Browser links to the Source Editor to
view the code.
|
|
Debugger
|
Provides an array of tools to
control and manage the debugging
process. By running the application or applet under a control panel, you can
stop and resume threads, set break points, trap exceptions, view threads in
alphabetical order, and see messages.
|
|
Applet Tester
|
Similarly to appletviewer,
Applet Tester
lets you run and test your applet. Use Build Manager to compile your applet,
then run it with Applet Tester.
|
|
Online Help
|
Is organized in to
the topics "Getting
Started", "Debugging Applets", "Building Applets", "Managing
Applets", and "Browsing Source". There are also buttons
for a table of contents and index.
|
|
Visual Java
|
An integrated Java
GUI builder that has
a point-and-click interface with a pallet of customizable prebuilt GUI foundation
widgets.
|