CORE JAVA 8
COLLECTIONS 8
JDBC 20
JDBC INTRODUCTION....................................................................................20
JDBC PRODUCT COMPONENTS..............................................................................21
JDBC ARCHITECTURE.......................................................................................23
A RELATIONAL DATABASE OVERVIEW........................................................................25
DEPLOYMENT 48
THREADS 50
REFLECTION 50
USES OF REFLECTION........................................................................................50
DRAWBACKS OF REFLECTION.................................................................................50
TRAIL LESSONS..............................................................................................51
SECURITY 58
RMI 59
SWINGS 91
JAAS 100
INTERNATIONALIZATION 100
JUNIT 106
JNDI 106
NAMING CONCEPTS.........................................................................................107
DIRECTORY PACKAGE.......................................................................................116
LDAP PACKAGE...........................................................................................117
EVENT PACKAGE............................................................................................118
SERVICE PROVIDER PACKAGE..............................................................................119
J2EE 121
SERVLETS 121
JSP 121
EJB 121
3
STRUTS 121
JMS 121
HIBERNATE 121
SAX 121
DOM 121
DAO 121
COMPOSITION 121
AGGREGATION 121
BRIDGE 121
SINGLETON 121
BUILDER 121
ITERATE 121
OBSERVER 121
STATE 122
4
STRATEGY 122
VISITOR 122
FLYWEIGHT 122
PROXY 122
ROUTER 122
TRANSLATION 122
SOAP 122
UDDI 122
WSDL 122
XML 122
DDL 122
XSL 122
LINK 122
PATH 122
XQUERY 122
DATABASE 122
DB2 122
HTML 123
CSS 123
AJAX 123
METHODOLOGIES 123
OOAD 123
OODB 123
SAD 123
TOOLS 123
ECLISPE3.2 123
ANT 123
6
MAVEN 123
STRATEGIES 123
WINDOWS 124
UNIX 124
CONTENTS................................................................................................125
INTRODUCTION...........................................................................................126
THE EXTENSION MECHANISM...........................................................................127
ARCHITECTURE..............................................................................................127
OPTIONAL PACKAGE DEPLOYMENT..........................................................................128
BUNDLED OPTIONAL PACKAGES............................................................................129
INSTALLED OPTIONAL PACKAGES...........................................................................131
OPTIONAL PACKAGE SEALING..........................................................................132
OPTIONAL PACKAGE SECURITY.........................................................................133
RELATED APIS..........................................................................................134
GENERIC 134
7
JMX 141
INSTRUMENTATION..........................................................................................144
JMX AGENT...............................................................................................145
REMOTE MANAGEMENT.....................................................................................146
SECURITY 149
1 INTRODUCTION........................................................................................149
2 JAVA LANGUAGE SECURITY AND BYTECODE VERIFICATION........................................150
3 BASIC SECURITY ARCHITECTURE....................................................................151
SECURITY PROVIDERS......................................................................................152
FILE LOCATIONS............................................................................................153
4 CRYPTOGRAPHY........................................................................................154
5 PUBLIC KEY INFRASTRUCTURE.......................................................................155
KEY AND CERTIFICATE STORAGE...........................................................................156
PKI TOOLS................................................................................................157
6 AUTHENTICATION......................................................................................158
7 SECURE COMMUNICATION............................................................................159
SSL/TLS.................................................................................................159
SASL.....................................................................................................160
GSS-API AND KERBEROS................................................................................161
8 ACCESS CONTROL.....................................................................................162
PERMISSIONS...............................................................................................162
POLICY.....................................................................................................163
ACCESS CONTROL ENFORCEMENT...........................................................................164
9 FOR MORE INFORMATION ...........................................................................165
APPENDIX A CLASSES SUMMARY.......................................................................166
APPENDIX B TOOLS SUMMARY.........................................................................169
APPENDIX C BUILT-IN PROVIDERS....................................................................170
INTRODUCTION 172
Core Java
Collections
Sources:
http://java.sun.com/docs/books/tutorial/collections/interfaces/co
llection.html
Lesson: Interfaces
Note that all the core collection interfaces are generic. For
example, this is the declaration of the Collection interface.
The <E> syntax tells you that the interface is generic. When
you declare a Collection instance you can and should specify the
type of object contained in the collection. Specifying the type
allows the compiler to verify (at compile-time) that the type of
object you put into the collection is correct, thus reducing errors
at runtime. For information on generic types, see the Generics
lesson.
// Bulk operations
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c); //optional
boolean removeAll(Collection<?> c); //optional
boolean retainAll(Collection<?> c); //optional
void clear(); //optional
16
// Array operations
Object[] toArray();
<T> T[] toArray(T[] a);
}
Traversing Collections
There are two ways to traverse collections: (1) with the for-
each construct and (2) by using Iterators.
for-each Construct
The for-each construct allows you to concisely traverse a
collection or array using a for loop — see The for Statement. The
following code uses the for-each construct to print out each
element of a collection on a separate line.
System.out.println(o);
Iterators
An Iterator is an object that enables you to traverse through a
collection and to remove elements from the collection selectively,
if desired. You get an Iterator for a collection by calling its
iterator method. The following is the Iterator interface.
c.removeAll(Collections.singleton(e));
c.removeAll(Collections.singleton(null));
Object[] a = c.toArray();
20
JDBC
Introduces an API for connectivity between the Java applications
and a wide range of databases and a data sources.
JDBC(TM) Database Access
The JDBC™ API was designed to keep simple things simple. This
means that the JDBC makes everyday database tasks easy. This
trail walks you through examples of using JDBC to execute
common SQL statements, and perform other objectives common
to database applications.
JDBC Basics covers the JDBC API, which is included in the Java™
SE 6 release.
By the end of the first lesson, you will know how to use the basic
JDBC API to create tables, insert values into them, query the
tables, retrieve the results of the queries, and update the tables.
In this process, you will learn how to use simple statements and
prepared statements, and you will see an example of a stored
procedure. You will also learn how to perform transactions and
how to catch exceptions and warnings.
JDBC Introduction
21
The JDBC API is a Java API that can access any kind of tabular
data, especially data stored in a Relational Database.
The JDBC driver test suite helps you to determine that JDBC
drivers will run your program. These tests are not
comprehensive or exhaustive, but they do exercise many of
the important features in the JDBC API.
4. JDBC-ODBC Bridge —
This Trail uses the first two of these these four JDBC components
to connect to a database and then build a java program that uses
SQL commands to communicate with a test Relational Database.
The last two components are used in specialized environments to
test web applications, or to communicate with ODBC-aware
DBMSs.
JDBC Architecture
Integrity Rules
Relational tables follow certain integrity rules to ensure that the
data they contain stay accurate and are always accessible. First,
the rows in a relational table should all be distinct. If there are
duplicate rows, there can be problems resolving which of two
possible selections is the correct one. For most DBMSs, the user
can specify that duplicate rows are not allowed, and if that is
done, the DBMS will prevent the addition of any rows that
duplicate an existing row.
The primary key for this table would generally be the employee
number because each one is guaranteed to be different. (A
number is also more efficient than a string for making
comparisons.) It would also be possible to use First_Name and
Last_Name because the combination of the two also identifies
just one row in our sample database. Using the last name alone
would not work because there are two employees with the last
name of "Washington." In this particular case the first names are
all different, so one could conceivably use that column as a
primary key, but it is best to avoid using a column where
duplicates could occur. If Elizabeth Taylor gets a job at this
company and the primary key is First_Name, the RDBMS will not
allow her name to be added (if it has been specified that no
duplicates are permitted). Because there is already an Elizabeth
in the table, adding a second one would make the primary key
useless as a way of identifying just one row. Note that although
using First_Name and Last_Name is a unique composite key for
this example, it might not be unique in a larger database. Note
also that Table 1.2 assumes that there can be only one car per
employee.
SELECT Statements
SQL is a language designed to be used with relational databases.
There is a set of basic SQL commands that is considered
28
The result set (the set of rows that satisfy the requirement of not
having null in the Car_Number column) follows. The first name
and last name are printed for each row that satisfies the
requirement because the SELECT statement (the first line)
specifies the columns First_Name and Last_Name. The FROM
clause (the second line) gives the table from which the columns
will be selected.
FIRST_NAME LAST_NAME
---------- -----------
Axel Washington
Florence Wojokowski
The following code produces a result set that includes the whole
table because it asks for all of the columns in the table
Employees with no restrictions (no WHERE clause). Note that SELECT
* means "SELECT all columns."
SELECT *
FROM Employees
29
WHERE Clauses
The WHERE clause in a SELECT statement provides the criteria for
selecting values. For example, in the following code fragment,
values will be selected only if they occur in a row in which the
column Last_Name begins with the string 'Washington'.
SELECT First_Name, Last_Name
FROM Employees
WHERE Last_Name LIKE 'Washington%'
The code fragment below has a WHERE clause that uses the equal
sign (=) to compare numbers. It selects the first and last name of
the employee who is assigned car 12.
SELECT First_Name, Last_Name
FROM Employees
WHERE Car_Number = 12
The next code fragment selects the first and last names of
employees whose employee number is greater than 10005:
SELECT First_Name, Last_Name
FROM Employees
30
Joins
A distinguishing feature of relational databases is that it is
possible to get data from more than one table in what is called a
join. Suppose that after retrieving the names of employees who
have company cars, one wanted to find out who has which car,
including the make, model, and year of car. This information is
stored in another table, Cars, shown in Table 1.3.
The following code asks for the first and last names of employees
who have company cars and for the make, model, and year of
those cars. Note that the FROM clause lists both Employees and
Cars because the requested data is contained in both tables.
Using the table name and a dot (.) before the column name
indicates which table contains the column.
SELECT Employees.First_Name, Employees.Last_Name, Cars.Make,
Cars.Model, Cars.Year
FROM Employees, Cars
WHERE Employees.Car_Number = Cars.Car_Number
This returns a result set that will look similar to the following:
FIRST_NAME LAST_NAME MAKE MODEL YEAR
----------- ------------ -------- --------- -------
Axel Washington Honda CivicDX 1996
Florence Wojokowski Toyota Corolla 1999
Earlier JDBC API versions added new capabilities for a result set's
cursor, allowing it to move both forward and backward and also
allowing it to move to a specified row or to a row whose position
is relative to another row.
34
Transactions
When one user is accessing data in a database, another user
may be accessing the same data at the same time. If, for
instance, the first user is updating some columns in a table at the
same time the second user is selecting columns from that same
table, it is possible for the second user to get partly old data and
partly updated data. For this reason, DBMSs use transactions to
maintain data in a consistent state (data consistency) while
allowing more than one user to access a database at the same
time (data concurrency).
Stored Procedures
A stored procedure is a group of SQL statements that can be
called by name. In other words, it is executable code, a mini-
program, that performs a particular task that can be invoked the
same way one can call a function or method. Traditionally, stored
procedures have been written in a DBMS-specific programming
language. The latest generation of database products allows
35
try {
con = DriverManager.getConnection("jdbc:default:connection");
pstmt = con.prepareStatement(
"UPDATE EMPLOYEES SET CAR_NUMBER = ? " +
"WHERE EMPLOYEE_NUMBER = ?");
pstmt.setInt(1, carNo);
pstmt.setInt(2, empNo);
pstmt.executeUpdate();
}
finally {
if (pstmt != null) pstmt.close();
}
36
}
}
Metadata
Databases store user data, and they also store information about
the database itself. Most DBMSs have a set of system tables,
which list tables in the database, column names in each table,
primary keys, foreign keys, stored procedures, and so forth. Each
DBMS has its own functions for getting information about table
layouts and database features. JDBC provides the interface
DatabaseMetaData, which a driver writer must implement so that
its methods return information about the driver and/or DBMS for
which the driver is written. For example, a large number of
methods return whether or not the driver supports a particular
functionality. This interface gives users and tools a standardized
way to get metadata. In general, developers writing tools and
drivers are the ones most likely to be concerned with metadata.
JDBC Architecture
Integrity Rules
Relational tables follow certain integrity rules to ensure that the
data they contain stay accurate and are always accessible. First,
the rows in a relational table should all be distinct. If there are
duplicate rows, there can be problems resolving which of two
possible selections is the correct one. For most DBMSs, the user
can specify that duplicate rows are not allowed, and if that is
done, the DBMS will prevent the addition of any rows that
duplicate an existing row.
39
The primary key for this table would generally be the employee
number because each one is guaranteed to be different. (A
number is also more efficient than a string for making
comparisons.) It would also be possible to use First_Name and
Last_Name because the combination of the two also identifies
just one row in our sample database. Using the last name alone
40
would not work because there are two employees with the last
name of "Washington." In this particular case the first names are
all different, so one could conceivably use that column as a
primary key, but it is best to avoid using a column where
duplicates could occur. If Elizabeth Taylor gets a job at this
company and the primary key is First_Name, the RDBMS will not
allow her name to be added (if it has been specified that no
duplicates are permitted). Because there is already an Elizabeth
in the table, adding a second one would make the primary key
useless as a way of identifying just one row. Note that although
using First_Name and Last_Name is a unique composite key for
this example, it might not be unique in a larger database. Note
also that Table 1.2 assumes that there can be only one car per
employee.
SELECT Statements
SQL is a language designed to be used with relational databases.
There is a set of basic SQL commands that is considered
standard and is used by all RDBMSs. For example, all RDBMSs
use the SELECT statement.
The result set (the set of rows that satisfy the requirement of not
having null in the Car_Number column) follows. The first name
and last name are printed for each row that satisfies the
requirement because the SELECT statement (the first line)
41
The following code produces a result set that includes the whole
table because it asks for all of the columns in the table
Employees with no restrictions (no WHERE clause). Note that SELECT
* means "SELECT all columns."
SELECT *
FROM Employees
WHERE Clauses
The WHERE clause in a SELECT statement provides the criteria for
selecting values. For example, in the following code fragment,
values will be selected only if they occur in a row in which the
column Last_Name begins with the string 'Washington'.
SELECT First_Name, Last_Name
FROM Employees
WHERE Last_Name LIKE 'Washington%'
The code fragment below has a WHERE clause that uses the equal
sign (=) to compare numbers. It selects the first and last name of
the employee who is assigned car 12.
SELECT First_Name, Last_Name
FROM Employees
WHERE Car_Number = 12
The next code fragment selects the first and last names of
employees whose employee number is greater than 10005:
SELECT First_Name, Last_Name
FROM Employees
WHERE Employee_Number > 10005
Joins
A distinguishing feature of relational databases is that it is
possible to get data from more than one table in what is called a
join. Suppose that after retrieving the names of employees who
have company cars, one wanted to find out who has which car,
43
The following code asks for the first and last names of employees
who have company cars and for the make, model, and year of
those cars. Note that the FROM clause lists both Employees and
Cars because the requested data is contained in both tables.
Using the table name and a dot (.) before the column name
indicates which table contains the column.
SELECT Employees.First_Name, Employees.Last_Name, Cars.Make,
Cars.Model, Cars.Year
FROM Employees, Cars
WHERE Employees.Car_Number = Cars.Car_Number
44
This returns a result set that will look similar to the following:
FIRST_NAME LAST_NAME MAKE MODEL YEAR
----------- ------------ -------- --------- -------
Axel Washington Honda CivicDX 1996
Florence Wojokowski Toyota Corolla 1999
zero, one, or many. A user can access the data in a result set one
row at a time, and a cursor provides the means to do that. A
cursor can be thought of as a pointer into a file that contains the
rows of the result set, and that pointer has the ability to keep
track of which row is currently being accessed. A cursor allows a
user to process each row of a result set from top to bottom and
consequently may be used for iterative processing. Most DBMSs
create a cursor automatically when a result set is generated.
Earlier JDBC API versions added new capabilities for a result set's
cursor, allowing it to move both forward and backward and also
allowing it to move to a specified row or to a row whose position
is relative to another row.
Transactions
When one user is accessing data in a database, another user
may be accessing the same data at the same time. If, for
instance, the first user is updating some columns in a table at the
same time the second user is selecting columns from that same
table, it is possible for the second user to get partly old data and
partly updated data. For this reason, DBMSs use transactions to
maintain data in a consistent state (data consistency) while
allowing more than one user to access a database at the same
time (data concurrency).
Stored Procedures
A stored procedure is a group of SQL statements that can be
called by name. In other words, it is executable code, a mini-
program, that performs a particular task that can be invoked the
same way one can call a function or method. Traditionally, stored
procedures have been written in a DBMS-specific programming
language. The latest generation of database products allows
stored procedures to be written using the Java programming
language and the JDBC API. Stored procedures written in the Java
programming language are bytecode portable between DBMSs.
Once a stored procedure is written, it can be used and reused
because a DBMS that supports stored procedures will, as its
name implies, store it in the database.
try {
con = DriverManager.getConnection("jdbc:default:connection");
pstmt = con.prepareStatement(
"UPDATE EMPLOYEES SET CAR_NUMBER = ? " +
"WHERE EMPLOYEE_NUMBER = ?");
pstmt.setInt(1, carNo);
pstmt.setInt(2, empNo);
pstmt.executeUpdate();
}
finally {
if (pstmt != null) pstmt.close();
}
}
}
Metadata
Databases store user data, and they also store information about
the database itself. Most DBMSs have a set of system tables,
which list tables in the database, column names in each table,
primary keys, foreign keys, stored procedures, and so forth. Each
DBMS has its own functions for getting information about table
layouts and database features. JDBC provides the interface
DatabaseMetaData, which a driver writer must implement so that
its methods return information about the driver and/or DBMS for
which the driver is written. For example, a large number of
methods return whether or not the driver supports a particular
functionality. This interface gives users and tools a standardized
way to get metadata. In general, developers writing tools and
drivers are the ones most likely to be concerned with metadata.
Deployment
Packaging Programs in JAR Files
The JavaTM Archive (JAR) file format enables you to bundle
multiple files into a single archive file. Typically a JAR file
49
Threads
Reflection
The Reflection API
Uses of Reflection
Reflection is commonly used by programs which require the
ability to examine or modify the runtime behavior of applications
running in the Java virtual machine. This is a relatively advanced
feature and should be used only by developers who have a
strong grasp of the fundamentals of the language. With that
caveat in mind, reflection is a powerful technique and can enable
applications to perform operations which would otherwise be
impossible.
Extensibility Features
An application may make use of external, user-defined
classes by creating instances of extensibility objects using
their fully-qualified names.
Class Browsers and Visual Development Environments
A class browser needs to be able to enumerate the members
of classes. Visual development environments can benefit
from making use of type information available in reflection
to aid the developer in writing correct code.
Debuggers and Test Tools
Debuggers need to be able to examine private members on
classes. Test harnesses can make use of reflection to
systematically call a discoverable set APIs defined on a
class, to insure a high level of code coverage in a test suite.
Drawbacks of Reflection
Reflection is powerful, but should not be used indiscriminately. If
it is possible to perform an operation without using reflection,
then it is preferable to avoid using it. The following concerns
should be kept in mind when accessing code via reflection.
Performance Overhead
51
Trail Lessons
This trail covers common uses of reflection for accessing and
manipulating classes, fields, methods, and constructors. Each
lesson contains code examples, tips, and troubleshooting
information.
Classes
This lesson shows the various ways to obtain a Class object
and use it to examine properties of a class, including its
declaration and contents.
Members
This lesson describes how to use the Reflection APIs to find
the fields, methods, and constructors of a class. Examples
are provided for setting and getting field values, invoking
methods, and creating new instances of objects using
specific constructors.
52
Not all modifiers are allowed on all classes, for example an interface cannot be
final and an enum cannot be abstract. java.lang.reflect.Modifier
contains declarations for all possible modifiers. It also contains methods which
may be used to decode the set of modifiers returned by Class.getModifiers().
import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import static java.lang.System.out;
out.format("Modifiers:%n %s%n%n",
Modifier.toString(c.getModifiers()));
out.format("Type Parameters:%n");
TypeVariable[] tv = c.getTypeParameters();
if (tv.length != 0) {
out.format(" ");
for (TypeVariable t : tv)
out.format("%s ", t.getName());
out.format("%n%n");
} else {
out.format(" -- No Type Parameters --%n%n");
}
out.format("Implemented Interfaces:%n");
Type[] intfs = c.getGenericInterfaces();
if (intfs.length != 0) {
for (Type intf : intfs)
out.format(" %s%n", intf.toString());
out.format("%n");
} else {
out.format(" -- No Implemented Interfaces --%n
%n");
}
out.format("Inheritance Path:%n");
List<Class> l = new ArrayList<Class>();
printAncestor(c, l);
if (l.size() != 0) {
for (Class<?> cl : l)
out.format(" %s%n", cl.getCanonicalName());
out.format("%n");
} else {
out.format(" -- No Super Classes --%n%n");
}
out.format("Annotations:%n");
Annotation[] ann = c.getAnnotations();
if (ann.length != 0) {
for (Annotation a : ann)
out.format(" %s%n", a.toString());
out.format("%n");
} else {
55
Modifiers:
public abstract interface
Type Parameters:
K V
Implemented Interfaces:
java.util.concurrent.ConcurrentMap<K, V>
java.util.NavigableMap<K, V>
Inheritance Path:
-- No Super Classes --
Annotations:
-- No Annotations --
This is the actual declaration for
java.util.concurrent.ConcurrentNavigableMap in the source code:
public interface ConcurrentNavigableMap<K,V>
56
Modifiers:
public abstract final
Type Parameters:
-- No Type Parameters --
Implemented Interfaces:
interface java.lang.Cloneable
interface java.io.Serializable
Inheritance Path:
java.lang.Object
Annotations:
-- No Annotations --
Since arrays are runtime objects, all of the type information is defined by the Java
virtual machine. In particular, arrays implement Cloneable and
java.io.Serializable and their direct superclass is always Object.
$ java ClassDeclarationSpy java.io.InterruptedIOException
Class:
java.io.InterruptedIOException
Modifiers:
public
Type Parameters:
-- No Type Parameters --
Implemented Interfaces:
-- No Implemented Interfaces --
57
Inheritance Path:
java.io.IOException
java.lang.Exception
java.lang.Throwable
java.lang.Object
Annotations:
-- No Annotations --
From the inheritance path, it may be deduced that
java.io.InterruptedIOException is a checked exception because
RuntimeException is not present.
$ java ClassDeclarationSpy java.security.Identity
Class:
java.security.Identity
Modifiers:
public abstract
Type Parameters:
-- No Type Parameters --
Implemented Interfaces:
interface java.security.Principal
interface java.io.Serializable
Inheritance Path:
java.lang.Object
Annotations:
@java.lang.Deprecated()
This output shows that java.security.Identity, a deprecated API, possesses
the annotation java.lang.Deprecated. This may be used by reflective code to
detect deprecated APIs.
Note: Not all annotations are available via reflection. Only those which have a
java.lang.annotation.RetentionPolicy of RUNTIME are accessible. Of the
three annotations pre-defined in the language @Deprecated, @Override, and
@SuppressWarnings only @Deprecated is available at runtime.
58
Security
Security Features in Java SE
In this trail you'll learn how the built-in Java™ security features protect you from
malevolent programs. You'll see how to use tools to control access to resources, to
generate and to check digital signatures, and to create and to manage keys needed
for signature generation and checking. You'll also see how to incorporate
cryptography services, such as digital signature generation and checking, into your
programs.
The security features provided by the Java Development Kit (JDK™) are intended
for a variety of audiences:
Developers:
RMI
The Java Remote Method Invocation (RMI) system allows an object running in
one Java virtual machine to invoke methods on an object running in another Java
virtual machine. RMI provides for remote communication between programs
written in the Java programming language.
Note: If you are connecting to an existing IDL program, you should use Java IDL
rather than RMI.
This trail provides a brief overview of the RMI system and then walks through a
complete client/server example that uses RMI's unique capabilities to load and to
execute user-defined tasks at runtime. The server in the example implements a
generic compute engine, which the client uses to compute the value of .
Compiling Sources
As with any Java program, you use the javac compiler to compile
the source files. The source files contain the declarations of the
remote interfaces, their implementations, any other server
classes, and the client classes.
Note: With versions prior to Java Platform, Standard Edition 5.0,
an additional step was required to build stub classes, by using
the rmic compiler. However, this step is no longer necessary.
The rest of this section walks through the steps used to create a
compute engine.
The novel aspect of the compute engine is that the tasks it runs
do not need to be defined when the compute engine is written or
64
started. New kinds of tasks can be created at any time and then
given to the compute engine to be run. The only requirement of a
task is that its class implement a particular interface. The code
needed to accomplish the task can be downloaded by the RMI
system to the compute engine. Then, the compute engine runs
the task, using the resources on the machine on which the
compute engine is running.
provides the rest of the code that makes up the server program,
including a main method that creates an instance of the remote
object, registers it with the RMI registry, and sets up a security
manager.
Designing a Remote Interface
At the core of the compute engine is a protocol that enables tasks to be submitted
to the compute engine, the compute engine to run those tasks, and the results of
those tasks to be returned to the client. This protocol is expressed in the interfaces
that are supported by the compute engine. The remote communication for this
protocol is illustrated in the following figure.
Each interface contains a single method. The compute engine's remote interface,
Compute, enables tasks to be submitted to the engine. The client interface, Task,
defines how the compute engine executes a submitted task.
import java.rmi.Remote;
import java.rmi.RemoteException;
The second interface needed for the compute engine is the Task interface, which
is the type of the parameter to the executeTask method in the Compute interface.
The compute.Task interface defines the interface between the compute engine
and the work that it needs to do, providing the way to start the work. Here is the
source code for the Task interface:
package compute;
The Task interface defines a single method, execute, which has no parameters
and throws no exceptions. Because the interface does not extend Remote, the
method in this interface doesn't need to list java.rmi.RemoteException in its
throws clause.
The Task interface has a type parameter, T, which represents the result type of the
task's computation. This interface's execute method returns the result of the
computation and thus its return type is T.
The Compute interface's executeTask method, in turn, returns the result of the
execution of the Task instance passed to it. Thus, the executeTask method has
its own type parameter, T, that associates its own return type with the result type
of the passed Task instance.
RMI uses the Java object serialization mechanism to transport objects by value
between Java virtual machines. For an object to be considered serializable, its
class must implement the java.io.Serializable marker interface. Therefore,
classes that implement the Task interface must also implement Serializable, as
must the classes of objects used for task results.
Different kinds of tasks can be run by a Compute object as long as they are
implementations of the Task type. The classes that implement this interface can
67
contain any data needed for the computation of the task and any other methods
needed for the computation.
Here is how RMI makes this simple compute engine possible. Because RMI can
assume that the Task objects are written in the Java programming language,
implementations of the Task object that were previously unknown to the compute
engine are downloaded by RMI into the compute engine's Java virtual machine as
needed. This capability enables clients of the compute engine to define new kinds
of tasks to be run on the server machine without needing the code to be explicitly
installed on that machine.
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import compute.Compute;
import compute.Task;
public ComputeEngine() {
super();
}
System.err.println("ComputeEngine exception:");
e.printStackTrace();
}
}
}
Some object types do not meet any of these criteria and thus
cannot be passed to or returned from a remote method. Most of
these objects, such as threads or file descriptors, encapsulate
information that makes sense only within a single address space.
Many of the core classes, including the classes in the packages
java.lang and java.util, implement the Serializable interface.
The ComputeEngine class creates a name for the object with the
following statement:
String name = "Compute";
The code then adds the name to the RMI registry running on the
server. This step is done later with the following statements:
Registry registry = LocateRegistry.getRegistry();
registry.rebind(name, stub);
Once the server has registered with the local RMI registry, it
prints a message indicating that it is ready to start handling calls.
Then, the main method completes. It is not necessary to have a
thread wait to keep the server alive. As long as there is a
reference to the ComputeEngine object in another Java virtual
machine, local or remote, the ComputeEngine object will not be
shut down or garbage collected. Because the program binds a
reference to the ComputeEngine in the registry, it is reachable from
a remote client, the registry itself. The RMI system keeps the
ComputeEngine's process running. The ComputeEngine is available to
accept calls and won't be reclaimed until its binding is removed
from the registry and no remote clients hold a remote reference
to the ComputeEngine object.
Two separate classes make up the client in our example. The first class,
ComputePi, looks up and invokes a Compute object. The second class, Pi,
implements the Task interface and defines the work to be done by the compute
engine. The job of the Pi class is to compute the value of to some number of
decimal places.
The code that invokes a Compute object's methods must obtain a reference to that
object, create a Task object, and then request that the task be executed. The
definition of the task class Pi is shown later. A Pi object is constructed with a
single argument, the desired precision of the result. The result of the task
execution is a java.math.BigDecimal representing calculated to the specified
precision.
Here is the source code for client.ComputePi, the main client class:
package client;
import java.rmi.registry.LocateRegistry;
77
import java.rmi.registry.Registry;
import java.math.BigDecimal;
import compute.Compute;
After installing a security manager, the client constructs a name to use to look up a
Compute remote object, using the same name used by ComputeEngine to bind its
remote object. Also, the client uses the LocateRegistry.getRegistry API to
synthesize a remote reference to the registry on the server's host. The value of the
first command-line argument, args[0], is the name of the remote host on which
the Compute object runs. The client then invokes the lookup method on the
registry to look up the remote object by name in the server host's registry. The
particular overload of LocateRegistry.getRegistry used, which has a single
String parameter, returns a reference to a registry at the named host and the
default registry port, 1099. You must use an overload that has an int parameter if
the registry is created on a port other than 1099.
78
Next, the client creates a new Pi object, passing to the Pi constructor the value of
the second command-line argument, args[1], parsed as an integer. This
argument indicates the number of decimal places to use in the calculation. Finally,
the client invokes the executeTask method of the Compute remote object. The
object passed into the executeTask invocation returns an object of type
BigDecimal, which the program stores in the variable result. Finally, the
program prints the result. The following figure depicts the flow of messages
among the ComputePi client, the rmiregistry, and the ComputeEngine.
The Pi class implements the Task interface and computes the value of to a
specified number of decimal places. For this example, the actual algorithm is
unimportant. What is important is that the algorithm is computationally expensive,
meaning that you would want to have it executed on a capable server.
Here is the source code for client.Pi, the class that implements the Task
interface:
package client;
import compute.Task;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* Construct a task to calculate pi to the specified
* precision.
*/
public Pi(int digits) {
this.digits = digits;
}
/**
* Calculate pi.
*/
public BigDecimal execute() {
return computePi(digits);
}
/**
* Compute the value of pi to the specified number of
* digits after the decimal point. The value is
* computed using Machin's formula:
*
* pi/4 = 4*arctan(1/5) - arctan(1/239)
*
* and a power series expansion of arctan(x) to
* sufficient precision.
*/
public static BigDecimal computePi(int digits) {
int scale = digits + 5;
BigDecimal arctan1_5 = arctan(5, scale);
BigDecimal arctan1_239 = arctan(239, scale);
BigDecimal pi = arctan1_5.multiply(FOUR).subtract(
arctan1_239).multiply(FOUR);
return pi.setScale(digits,
BigDecimal.ROUND_HALF_UP);
}
/**
* Compute the value, in radians, of the arctangent of
* the inverse of the supplied integer to the specified
* number of digits after the decimal point. The value
* is computed using the power series expansion for the
80
* arc tangent:
*
* arctan(x) = x - (x^3)/3 + (x^5)/5 - (x^7)/7 +
* (x^9)/9 ...
*/
public static BigDecimal arctan(int inverseX,
int scale)
{
BigDecimal result, numer, term;
BigDecimal invX = BigDecimal.valueOf(inverseX);
BigDecimal invX2 =
BigDecimal.valueOf(inverseX * inverseX);
numer = BigDecimal.ONE.divide(invX,
scale, roundingMode);
result = numer;
int i = 1;
do {
numer =
numer.divide(invX2, scale, roundingMode);
int denom = 2 * i + 1;
term =
numer.divide(BigDecimal.valueOf(denom),
scale, roundingMode);
if ((i % 2) != 0) {
result = result.subtract(term);
} else {
result = result.add(term);
}
i++;
} while (term.compareTo(BigDecimal.ZERO) != 0);
return result;
}
}
Note that all serializable classes, whether they implement the Serializable
interface directly or indirectly, must declare a private static final field
named serialVersionUID to guarantee serialization compatibility between
versions. If no previous version of the class has been released, then the value of
this field can be any long value, similar to the 227L used by Pi, as long as the
value is used consistently in future versions. If a previous version of the class has
81
The most interesting feature of this example is that the Compute implementation
object never needs the Pi class's definition until a Pi object is passed in as an
argument to the executeTask method. At that point, the code for the class is
loaded by RMI into the Compute object's Java virtual machine, the execute
method is invoked, and the task's code is executed. The result, which in the case of
the Pi task is a BigDecimal object, is handed back to the calling client, where it
is used to print the result of the computation.
The fact that the supplied Task object computes the value of Pi is irrelevant to the
ComputeEngine object. You could also implement a task that, for example,
generates a random prime number by using a probabilistic algorithm. That task
would also be computationally intensive and therefore a good candidate for
passing to the ComputeEngine, but it would require very different code. This
code could also be downloaded when the Task object is passed to a Compute
object. In just the way that the algorithm for computing is brought in when
needed, the code that generates the random prime number would be brought in
when needed. The Compute object knows only that each object it receives
implements the execute method. The Compute object does not know, and does
not need to know, what the implementation does.
In this section, you learn how to compile the server and the
client programs that make up the compute engine example.
Finally, you run the server and client programs and consequently
compute the value of .
Compiling the Example Programs
In a real-world scenario in which a service such as the compute
engine is deployed, a developer would likely create a Java
Archive (JAR) file that contains the Compute and Task interfaces
for server classes to implement and client programs to use. Next,
a developer, perhaps the same developer of the interface JAR
file, would write an implementation of the Compute interface and
deploy that service on a machine available to clients. Developers
of client programs can use the Compute and the Task interfaces,
contained in the JAR file, and independently develop a task and
client program that uses a Compute service.
In this section, you learn how to set up the JAR file, server
classes, and client classes. You will see that the client's Pi class
will be downloaded to the server at runtime. Also, the Compute
and Task interfaces will be downloaded from the server to the
registry at runtime.
First, you need to build the interface JAR file to provide to server
and client developers.
Microsoft Windows:
cd c:\home\ann\src
85
Assume that user jones, the developer of the client classes, has
placed ComputePi.java and Pi.java in the directory
c:\home\jones\src\client on Windows or the directory
/home/jones/src/client on Solaris OS or Linux. He is deploying the
class files for the compute engine to download in a subdirectory
of his public_html directory, c:\home\jones\public_html\classes on
Windows or /home/jones/public_html/classes on Solaris OS or
Linux. This location is accessible through some web servers as
http://host:port/~jones/classes/.
need the compute.jar file in your class path when you build the
client classes. Assume that the compute.jar file is located in the
directory c:\home\jones\public_html\classes on Windows or the
directory /home/jones/public_html/classes on Solaris OS or Linux.
Given these paths, you can use the following commands to build
the client classes:
Microsoft Windows:
cd c:\home\jones\src
javac -cp c:\home\jones\public_html\classes\compute.jar
client\ComputePi.java client\Pi.java
mkdir c:\home\jones\public_html\classes\client
cp client\Pi.class
c:\home\jones\public_html\classes\client
Solaris OS or Linux:
cd /home/jones/src
javac -cp /home/jones/public_html/classes/compute.jar
client/ComputePi.java client/Pi.java
mkdir /home/jones/public_html/classes/client
cp client/Pi.class
/home/jones/public_html/classes/client
For both example policy files, all permissions are granted to the
classes in the program's local class path, because the local
application code is trusted, but no permissions are granted to
code downloaded from other locations. Therefore, the compute
engine server restricts the tasks that it executes (whose code is
not known to be trusted and might be hostile) from performing
any operations that require security permissions. The example
client's Pi task does not require any permissions to execute.
In this example, the policy file for the server program is named
server.policy, and the policy file for the client program is named
client.policy.
start rmiregistry
Solaris OS or Linux:
rmiregistry &
Microsoft Windows:
start rmiregistry 2001
Solaris OS or Linux:
rmiregistry 2001 &
Once the registry is started, you can start the server. You need to
make sure that both the compute.jar file and the remote object
implementation class are in your class path. When you start the
compute engine, you need to specify, using the
java.rmi.server.codebase property, where the server's classes are
network accessible. In this example, the server-side classes to be
made available for downloading are the Compute and Task
interfaces, which are available in the compute.jar file in the
public_html\classes directory of user ann. The compute engine
server is started on the host zaphod, the same host on which the
registry was started.
Microsoft Windows:
java -cp c:\home\ann\src;c:\home\ann\public_html\classes\compute.jar
-Djava.rmi.server.codebase=file:/c:/home/ann/public_html/classes/comp
ute.jar
-Djava.rmi.server.hostname=zaphod.east.sun.com
-Djava.security.policy=server.policy
engine.ComputeEngine
Solaris OS or Linux:
java -cp /home/ann/src:/home/ann/public_html/classes/compute.jar
-Djava.rmi.server.codebase=http://zaphod/~ann/classes/compute.jar
-Djava.rmi.server.hostname=zaphod.east.sun.com
-Djava.security.policy=server.policy
89
engine.ComputeEngine
The location where the client serves its classes (the Pi class)
by using the java.rmi.server.codebase property
The java.security.policy property, which is used to specify
the security policy file that contains the permissions you
intend to grant to various pieces of code
90
Start the client on another host (a host named ford, for example)
as follows:
Microsoft Windows:
java -cp c:\home\jones\src;c:\home\jones\public_html\classes\compute.jar
-Djava.rmi.server.codebase=file:/c:/home/jones/public_html/classes/
-Djava.security.policy=client.policy
client.ComputePi zaphod.east.sun.com 45
Solaris OS or Linux:
java -cp /home/jones/src:/home/jones/public_html/classes/compute.jar
-Djava.rmi.server.codebase=http://ford/~jones/classes/
-Djava.security.policy=client.policy
client.ComputePi zaphod.east.sun.com 45
Note that the class path is set on the command line so that the
interpreter can find the client classes and the JAR file containing
the interfaces. Also note that the value of the
java.rmi.server.codebase property, which specifies a directory
hierarchy, ends with a trailing slash.
Because the ComputePi client has both the Compute and the Task
interfaces available in its class path, it loads their definitions from
its class path, not from the server's codebase.
Swings
What is Swing?
To create a Java program with a graphical user interface (GUI),
you'll want to learn about Swing.
Swing is part of the Java Foundation Classes (JFC). The JFC also
include other features important to a GUI program, such as the
ability to add rich graphics functionality and the ability to create
a program that can work in different languages and by users with
different input devices.
The following list shows some of the features that Swing and the
Java Foundation Classes provide.
Data Transfer
Data transfer, via cut, copy, paste, and drag and drop, is
essential to almost any application. Support for data
transfer is built into Swing and works between Swing
components within an application, between Java
applications, and between Java and native applications.
Internationalization
This feature allows developers to build applications that can
interact with users worldwide in their own languages and
cultural conventions. Applications can be created that accept
input in languages that use thousands of different
characters, such as Japanese, Chinese, or Korean.
Accessibility API
People with disabilities use special software — assistive
technologies — that mediates the user experience for them.
Such software needs to obtain a wealth of information about
the running application in order to represent it in alternate
media: for a screen reader to read the screen with synthetic
speech or render it via a Braille display, for a screen
magnifier to track the caret and keyboard focus, for on-
screen keyboards to present dynamic keyboards of the
menu choices and toolbar items and dialog controls, and for
voice control systems to know what the user can control
with his or her voice. The accessibility API enables these
assistive technologies to get the information they need, and
to programmatically manipulate the elements that make up
the graphical user interface.
Undo Framework API
Swing's undo framework allows developers to provide
support for undo and redo. Undo support is built in to
Swing's text component. For other components, Swing
supports an unlimited number of actions to undo and redo,
and is easily adapted to an application. For example, you
could easily enable undo to add and remove elements from
a table.
Flexible Deployment Support
If you want your program to run within a browser window,
you can create it as an applet and run it using Java Plug-in,
which supports a variety of browsers, such as Internet
Explorer, Firefox, and Safari. If you want to create a
program that can be launched from a browser, you can do
this with Java Web Start. Of course, your application can
also run outside of browser as a standard desktop
application.
topLevelContainer.setContentPane(contentPane);
Note that only these three methods do this. This means that
getLayout() will not return the layout set with setLayout().
We've already told you about the content pane and the optional
menu bar. The two other components that a root pane adds are
a layered pane and a glass pane. The layered pane contains the
menu bar and content pane, and enables Z-ordering of other
components. The glass pane is often used to intercept input
events occuring over the top-level container, and can also be
used to paint over multiple components.
JAAS
Internationalization
Introduction
Internationalization is the process of designing an application so
that it can be adapted to various languages and regions without
engineering changes. Sometimes the term internationalization is
abbreviated as i18n, because there are 18 letters between the
first "i" and the last "n."
Before Internationalization
Suppose that you've written a program that displays three
messages, as follows:
public class NotI18N {
System.out.println("Hello.");
System.out.println("How are you?");
System.out.println("Goodbye.");
}
}
You've decided that this program needs to display these same
messages for people living in France and Germany. Unfortunately
your programming staff is not multilingual, so you'll need help
translating the messages into French and German. Since the
translators aren't programmers, you'll have to move the
messages out of the source code and into text files that the
translators can edit. Also, the program must be flexible enough
so that it can display the messages in other languages, but right
now no one knows what those languages will be.
After Internationalization
The source code for the internationalized program follows. Notice
that the text of the messages is not hardcoded.
import java.util.*;
String language;
String country;
102
if (args.length != 2) {
language = new String("en");
country = new String("US");
} else {
language = new String(args[0]);
country = new String(args[1]);
}
Locale currentLocale;
ResourceBundle messages;
messages = ResourceBundle.getBundle("MessagesBundle",
currentLocale);
System.out.println(messages.getString("greetings"));
System.out.println(messages.getString("inquiry"));
System.out.println(messages.getString("farewell"));
}
}
To compile and run this program, you need these source files:
I18NSample.java
MessagesBundle.properties
MessagesBundle_de_DE.properties
MessagesBundle_en_US.properties
MessagesBundle_fr_FR.properties
The next example creates Locale objects for the French language
in Canada and in France:
caLocale = new Locale("fr","CA");
frLocale = new Locale("fr","FR");
3. Create a ResourceBundle
ResourceBundle objects contain locale-specific objects. You use
ResourceBundle objects to isolate locale-sensitive data, such as
translatable text. In the sample program the ResourceBundle is
backed by the properties files that contain the message text we
want to display.
MessagesBundle_en_US.properties
MessagesBundle_fr_FR.properties
MessagesBundle_de_DE.properties
Now all you have to do is get the translated messages from the
ResourceBundle.
Conclusion
That's it. As you can see, internationalizing a program isn't too
difficult. It requires some planning and a little extra coding, but
the benefits are enormous. To provide you with an overview of
the internationalization process, the sample program in this
lesson was intentionally kept simple. As you read the lessons
that follow, you'll learn about the more advanced
internationalization features of the Java programming language.
JUnit
JNDI
Java Naming and Directory Interface(TM).
This trail describes JNDITM (Java Naming and Directory Interface) an API to
access the directory and naming services. Here you learn about the basic naming
and directory services and how to use JNDI to write simple applications to use
these services. The most popular directory service LDAP is used to demostrate the
use of JNDI to access the directory services.
Naming and Directory Concepts
107
Naming Concepts
A fundamental facility in any computing system is the naming
service--the means by which names are associated with objects
and objects are found based on their names. When using almost
any computer program or system, you are always naming one
object or another. For example, when you use an electronic mail
system, you must provide the name of the recipient. To access a
file in the computer, you must supply its name. A naming service
allows you to look up an object given its name.
Names
To look up an object in a naming system, you supply it the name
of the object. The naming system determines the syntax that the
name must follow. This syntax is sometimes called the naming
system's naming convention. A name is made up components. A
name's representation consist of a component separator marking
the components of the name.
108
Naming Component
Names
System Seperator
UNIXTM file
"/" /usr/hello
system
DNS "." sales.Wiz.COM
cn=Rosanna Lee, o=Sun,
LDAP "," and "="
c=US
Bindings
The association of a name with an object is called a binding. A
file name is bound to a file.
109
Context
A context is a set of name-to-object bindings. Every context has
an associated naming convention. A context always provides a
lookup (resolution) operation that returns the object, it typically
also provides operations such as those for binding names,
unbinding names, and listing bound names. A name in one
context object can be bound to another context object (called a
subcontext) that has the same naming convention.
Directory Concepts
Many naming services are extended with a directory service. A
directory service associates names with objects and also
associates such objects with attributes.
You not only can look up an object by its name but also get the
object's attributes or search for the object based on its attributes.
Attributes
A directory object can have attributes. For example, a printer
might be represented by a directory object that has as attributes
its speed, resolution, and color. A user might be represented by a
directory object that has as attributes the user's e-mail address,
various telephone numbers, postal mail address, and computer
account information.
Search Service
You can look up a directory object by supplying its name to the
directory service. Alternatively, many directories, such as those
based on the LDAP, support the notion of searches. When you
search, you can supply not a name but a query consisting of a
logical expression in which you specify the attributes that the
object or objects must have. The query is called a search filter.
This style of searching is sometimes called reverse lookup or
content-based searching. The directory service searches for and
returns the objects that satisfy the search filter.
all users that have the attribute "age" greater than 40 years.
all machines whose IP address starts with "192.113.50".
Architecture
The JNDI architecture consists of an API and a service provider
interface (SPI). Java applications use the JNDI API to access a
variety of naming and directory services. The SPI enables a
variety of naming and directory services to be plugged in
transparently, thereby allowing the Java application using the
JNDI API to access their services. See the following figure.
Packaging
JNDI is included in the Java SE Platform. To use the JNDI, you
must have the JNDI classes and one or more service providers.
The JDK includes service providers for the following
naming/directory services:
javax.naming
javax.naming.directory
115
javax.naming.ldap
javax.naming.event
javax.naming.spi
The next part of the lesson has a brief description of the JNDI
packages.
Naming Package
The javax.naming package contains classes and interfaces for
accessing naming services.
Context
The javax.naming package defines a Context interface, which is the
core interface for looking up, binding/unbinding, renaming
objects and creating and destroying subcontexts.
Lookup
The most commonly used operation is lookup(). You supply
lookup() the name of the object you want to look up, and it
returns the object bound to that name.
Bindings
listBindings() returns an enumeration of name-to-object
bindings. A binding is a tuple containing the name of the
bound object, the name of the object's class, and the object
itself.
List
list()is similar to listBindings(), except that it returns an
enumeration of names containing an object's name and the
name of the object's class. list() is useful for applications
such as browsers that want to discover information about
the objects bound within a context but that don't need all of
the actual objects. Although listBindings() provides all of the
same information, it is potentially a much more expensive
operation.
Name
116
Exceptions
The JNDI defines a class hierarchy for exceptions that can be
thrown in the course of performing naming and directory
operations. The root of this class hierarchy is NamingException.
Programs interested in dealing with a particular exception can
catch the corresponding subclass of the exception. Otherwise,
they should catch NamingException.
Directory and LDAP Packages
Directory Package
The javax.naming package to provide functionality for accessing
directory services in addition to naming services. This package
117
LDAP Package
The javax.naming.ldap package contains classes and interfaces for
using features that are specific to the LDAP v3 that are not
already covered by the more generic javax.naming.directory
package. In fact, most JNDI applications that use the LDAP will
find the javax.naming.directory package sufficient and will not
need to use the javax.naming.ldap package at all. This package is
primarily for those applications that need to use "extended"
operations, controls, or unsolicited notifications.
"Extended" Operation
In addition to specifying well defined operations such as
search and modify, the LDAP v3 (RFC 2251) specifies a way
to transmit yet-to-be defined operations between the LDAP
client and the server. These operations are called
"extended" operations. An "extended" operation may be
defined by a standards organization such as the Internet
Engineering Task Force (IETF) or by a vendor.
Controls
The LDAP v3 allows any request or response to be
augmented by yet-to-be defined modifiers, called controls .
A control sent with a request is a request control and a
control sent with a response is a response control . A control
may be defined by a standards organization such as the
IETF or by a vendor. Request controls and response controls
118
Event Package
The javax.naming.event package contains classes and interfaces for
supporting event notification in naming and directory services.
Event notification is described in detail in the trail.
Events
A NamingEvent represents an event that is generated by a
naming/directory service. The event contains a type that
identifies the type of event. For example, event types are
categorized into those that affect the namespace, such as
"object added," and those that do not, such as "object
changed."
Listeners
A NamingListener is an object that listens for NamingEvents.
Each category of event type has a corresponding type of
NamingListener. For example, a NamespaceChangeListener
represents a listener interested in namespace change events
and an ObjectChangeListener represents a listener interested
in object change events.
119
J2EE
Servlets
JSP
EJB
Struts
JMS
Hibernate
SAX
DOM
Design Patterns
Session façade
Front Controller
DAO
Chain of Responsibilities
Composition
Aggregation
Abstract Factory
Factory method
Bridge
Singleton
Builder
Iterate
Observer
122
State
Strategy
Visitor
Flyweight
Proxy
Router
Translation
Web Services
SOAP
UDDI
WSDL
Apache Axis
XML Technologies
XML
DDL
XSL
Link
Path
XQuery
Database
Oracle 9i(SQLPL/SQL)
DB2
Application Servers
123
WebLogic 9.1
JBoss 4.1.2
Apache Tomcat5.5
UML tools
Web Design
HTML
Java Script
CSS
AJAX
Methodologies
OOAD
OODB
SAD
Tools
Eclispe3.2
Ant
Maven
Batch Script
Shell script
Strategies
Requirement/Request Analysis
124
Configuration Tools
Operating Systems
Windows
Unix
Sub Topics
Extension Mechanism
for Support of Optional Packages
Documentation Contents
Overview
API Specification
* java.lang.ClassLoader
* java.lang.Package
* java.lang.Thread
* java.net.JarURLConnection
* java.net.URLClassLoader
* java.security.SecureClassLoader
API Enhancements
More Information
Contents
126
Introduction
The Extension Mechanism
Architecture
Optional Package Deployment
Bundled Optional Packages
Installed Optional Packages
Optional Package Sealing
Optional Package Security
Related APIs
Introduction
Note: Optional packages are the new name for what used to be
known as standard extensions. The "extension mechanism" is
that functionality of the JDK™ and JRE™ that supports the use of
optional packages.
Since optional packages extend the platform's core API, their use
should be judiciously applied. Most commonly they are used for
well standardized interfaces such as those defined by the Java
Community ProcessSM, although it may also be appropriate for site
wide interfaces. Optional packages are rarely appropriate for
interfaces used by a single, or small set of applications.
Currently, the URLs must be relative to the code base of the JAR
file for security reasons. Thus, remote optional packages will
originate from the same code base as the application.
Each relative URL is resolved against the code base that the
containing application or optional package was loaded from. If
the resulting URL is invalid or refers to a resource that cannot be
found then it is ignored.
The resulting URLs are used to extend the class path for the
application, applet, or servlet by inserting the URLs in the class
path immediately following the URL of the containing JAR file. Any
duplicate URLs are omitted. For example, given the following
class path:
a.jar b.jar
If optional package b.jar contained the following Class-Path
manifest attribute:
Class-Path: x.jar a.jar
Then the resulting application class path would be the following:
a.jar b.jar x.jar
Of course, if x.jar had dependencies of its own then these would
be added according to the same rules and so on for each
subsequent URL. In the actual implementation, JAR file
dependencies are processed lazily so that the JAR files are not
actually opened until needed.
131
A sealed JAR specifies that all packages defined by that JAR are
sealed unless overridden specifically for a package.
133
Related APIs
Several classes in the Java platform support the extension
mechanism, including:
*As used on this web site, the terms "Java Virtual Machine" or
"JVM" mean a virtual machine for the Java platform.
Generic
Introduction
135
Now, you might think that all we've accomplished is to move the
clutter around. Instead of a cast to Integer on line 3, we have
Integer as a type parameter on line 1'. However, there is a very
big difference here. The compiler can now check the type
correctness of the program at compile-time. When we say that
myIntList is declared with type List<Integer>, this tells us
something about the variable myIntList, which holds true
wherever and whenever it is used, and the compiler will
guarantee it. In contrast, the cast tells us something the
programmer thinks is true at a single point in the code.
Wildcards
Consider the problem of writing a routine that prints out all the
elements in a collection. Here's how you might write it in an
older version of the language (i.e., a pre-5.0 release):
void printCollection(Collection c) {
Iterator i = c.iterator();
for (k = 0; k < c.size(); k++) {
System.out.println(i.next());
}
138
}
And here is a naive attempt at writing it using generics (and the
new for loop syntax):
void printCollection(Collection<Object> c) {
for (Object e : c) {
System.out.println(e);
}
}
The problem is that this new version is much less useful than the
old one. Whereas the old code could be called with any kind of
collection as a parameter, the new code only takes
Collection<Object>, which, as we've just demonstrated, is not a
supertype of all kinds of collections!
Since we don't know what type that is, we cannot pass anything
in. The sole exception is null, which is a member of every type.
On the other hand, given a List<?>, we can call get() and make
use of the result. The result type is an unknown type, but we
always know that it is an object. It is therefore safe to assign the
result of get() to a variable of type Object or pass it as a
parameter where the type Object is expected.
Bounded Wildcards
Consider a simple drawing application that can draw shapes such
as rectangles and circles. To represent these shapes within the
program, you could define a class hierarchy such as this:
public abstract class Shape {
public abstract void draw(Canvas c);
}
JMX
Java Management Extensions provides a standard way of
managing resources such as applications, devices, and services.
The Java Management Extensions (JMX) technology is a standard part of the Java
Platform, Standard Edition (Java SE platform). The JMX technology was added to
the platform in the Java 2 Platform, Standard Edition (J2SE) 5.0 release.
The JMX technology provides a simple, standard way of managing resources such
as applications, devices, and services. Because the JMX technology is dynamic,
you can use it to monitor and manage resources as they are created, installed and
implemented. You can also use the JMX technology to monitor and manage the
Java Virtual Machine (Java VM).
The JMX specification defines the architecture, design patterns, APIs, and
services in the Java programming language for management and monitoring of
applications and networks.
Using the JMX technology, a given resource is instrumented by one or more Java
objects known as Managed Beans, or MBeans. These MBeans are registered in a
core-managed object server, known as an MBean server. The MBean server acts
as a management agent and can run on most devices that have been enabled for
the Java programming language.
The specifications define JMX agents that you use to manage any resources that
have been correctly configured for management. A JMX agent consists of an
MBean server, in which MBeans are registered, and a set of services for handling
the MBeans. In this way, JMX agents directly control resources and make them
available to remote management applications.
The way in which resources are instrumented is completely independent from the
management infrastructure. Resources can therefore be rendered manageable
regardless of how their management applications are implemented.
Instrumentation
JMX agent
Remote management
Instrumentation
To manage resources using the JMX technology, you must first
instrument the resources in the Java programming language. You
use Java objects known as MBeans to implement the access to
the resources' instrumentation. MBeans must follow the design
patterns and interfaces defined in the JMX specification. Doing so
ensures that all MBeans provide managed resource
instrumentation in a standardized way. In addition to standard
MBeans, the JMX specification also defines a special type of
MBean called an MXBean. An MXBean is an MBean that
references only a pre-defined set of data types. Other types of
MBean exist, but this trail will concentrate on standard MBeans
and MXBeans.
145
JMX Agent
A JMX technology-based agent (JMX agent) is a standard
management agent that directly controls resources and makes
them available to remote management applications. JMX agents
are usually located on the same machine as the resources they
control, but this arrangement is not a requirement.
When you implement a JMX agent, you do not need to know the
semantics or functions of the resources that it will manage. In
fact, a JMX agent does not even need to know which resources it
will serve because any resource instrumented in compliance with
the JMX specification can use any JMX agent that offers the
services that the resource requires. Similarly, the JMX agent does
not need to know the functions of the management applications
that will access it.
146
Remote Management
JMX technology instrumentation can be accessed in many
different ways, either through existing management protocols
such as the Simple Network Management Protocol (SNMP) or
through proprietary protocols. The MBean server relies on
protocol adaptors and connectors to make a JMX agent accessible
from management applications outside the agent's Java Virtual
Machine (Java VM).
The JMX technology can also be used to monitor and manage the
Java virtual machine (Java VM).
JConsole
The Java SE platform includes the JConsole monitoring and
management tool, which complies with the JMX specification.
JConsole uses the extensive instrumentation of the Java VM (the
platform MXBeans) to provide information about the performance
and resource consumption of applications that are running on the
Java platform.
Security
1. Implementation independence
2. Implementation interoperability
3. Algorithm extensibility
Security Providers
The java.security.Provider class encapsulates the notion of a
security provider in the Java platform. It specifies the provider's
name and lists the security services it implements. Multiple
providers may be configured at the same time, and are listed in
order of preference. When a security service is requested, the
highest priority provider that implements that service is selected.
File Locations
Certain aspects of Java security mentioned in this paper,
including the configuration of providers, may be customized by
setting security properties. You may set security properties
statically in the security properties file, which by default is the
java.security file in the lib/security directory of the directory
154
The tools and commands mentioned in this paper are all in the
~jre/bin directory, where ~jre stands for the directory in which
the JRE is installed. The cacerts file mentioned in Section 5 is in
~jre/lib/security.
4 Cryptography
The Java cryptography architecture is a framework for accessing
and developing cryptographic functionality for the Java platform.
It includes APIs for a large variety of cryptographic services,
including
The Java platform includes built-in providers for many of the most
commonly used cryptographic algorithms, including the RSA and
DSA signature algorithms, the DES, AES, and ARCFOUR
encryption algorithms, the MD5 and SHA-1 message digest
algorithms, and the Diffie-Hellman key agreement algorithm.
These default providers implement cryptographic algorithms in
Java code.
The Java platform includes API and provider support for X.509
digital certificates and certificate revocation lists (CRLs), as well
as PKIX-compliant certification path building and validation. The
classes related to PKI are located in the java.security and
java.security.cert packages.
156
The Java platform also includes an LDAP certificate store type (for
accessing certificates stored in an LDAP directory), as well as an
in-memory Collection certificate store type (for accessing
certificates managed in a java.util.Collection object).
PKI Tools
There are two built-in tools for working with keys, certificates,
and key stores:
6 Authentication
Authentication is the process of determining the identity of a
user. In the context of the Java runtime environment, it is the
process of identifying the user of an executing Java program. In
certain cases, this process may rely on the services described in
the "Cryptography" section (Section 4).
7 Secure Communication
The data that travels across a network can be accessed by
someone who is not the intended recipient. When the data
includes private information, such as passwords and credit card
numbers, steps must be taken to make the data unintelligible to
unauthorized parties. It is also important to ensure that you are
sending the data to the appropriate party, and that the data has
not been modified, either intentionally or unintentionally, during
transport.
SSL/TLS
The Java platform provides APIs and an implementation of the
SSL and TLS protocols that includes functionality for data
encryption, message integrity, server authentication, and
optional client authentication. Applications can use SSL/TLS to
160
provide for the secure passage of data between two peers over
any application protocol, such as HTTP on top of TCP/IP.
The Java platform also includes APIs that support the notion of
pluggable (provider-based) key managers and trust managers. A
key manager is encapsulated by the javax.net.ssl.KeyManager
class, and manages the keys used to perform authentication. A
trust manager is encapsulated by the TrustManager class (in the
same package), and makes decisions about who to trust based
on certificates in the key store it manages.
SASL
Simple Authentication and Security Layer (SASL) is an Internet
standard that specifies a protocol for authentication and optional
establishment of a security layer between client and server
applications. SASL defines how authentication data is to be
exchanged, but does not itself specify the contents of that data.
It is a framework into which specific authentication mechanisms
that specify the contents and semantics of the authentication
data can fit. There are a number of standard SASL mechanisms
defined by the Internet community for various security levels and
deployment scenarios.
The Java SASL API defines classes and interfaces for applications
that use SASL mechanisms. It is defined to be mechanism-
neutral; an application that uses the API need not be hardwired
into using any particular SASL mechanism. Applications can
select the mechanism to use based on desired security features.
The API supports both client and server applications. The
161
The Java GSS APIs are in the org.ietf.jgss package. The Java
platform also defines basic Kerberos classes, like
KerberosPrincipal and KerberosTicket, which are located in the
javax.security.auth.kerberos package.
8 Access Control
The access control architecture in the Java platform protects
access to sensitive resources (for example, local files) or
sensitive application code (for example, methods in a class). All
access control decisions are mediated by a security manager,
represented by the java.lang.SecurityManager class. A
SecurityManager must be installed into the Java runtime in order
to activate the access control checks.
Permissions
When Java code is loaded by a class loader into the Java runtime,
the class loader automatically associates the following
information with that code:
Note that the identity of the user executing the code is not
available at class loading time. It is the responsibility of
application code to authenticate the end user if necessary (for
example, as described in Section 6). Once the user has been
authenticated, the application can dynamically associate that
user with executing code by invoking the doAs method in the
javax.security.auth.Subject class.
Policy
As mentioned earlier, a limited set of default permissions are
granted to code by class loaders. Administrators have the ability
to flexibly manage additional code permissions via a security
policy.
http://java.sun.com/javase/6/docs/guide/security/index.html
166
http://java.sun.com/security/
http://java.sun.com/docs/books/security/index.html
security properties
Signature Creates and verifies
digital signatures
java.security.cert Certificate Represents a public
key certificate
CertStore Represents a
repository of
unrelated and
typically untrusted
certificates
javax.crypto Cipher Performs
encryption and
decryption
KeyAgreement Performs a key
exchange
javax.net.ssl KeyManager Manages keys used
to perform SSL/TLS
authentication
SSLEngine Produces/consumes
SSL/TLS packets,
allowing the
application freedom
to choose a
transport
mechanism
SSLSocket Represents a
network socket that
encapsulates
SSL/TLS support on
top of a normal
stream socket
TrustManager Makes decisions
about who to trust
in SSL/TLS
interactions (for
169
example, based on
trusted certificates
in key stores)
javax.security.auth Subject Represents a user
javax.security.auth.kerber KerberosPrincipal Represents a
os Kerberos principal
KerberosTicket Represents a
Kerberos ticket
javax.security.auth.login LoginContext Supports pluggable
authentication
javax.security.auth.spi LoginModule Implements a
specific
authentication
mechanism
javax.security.sasl Sasl Creates SaslClient
and SaslServer
objects
SaslClient Performs SASL
authentication as a
client
SaslServer Performs SASL
authentication as a
server
org.ietf.jgss GSSContext Encapsulates a
GSS-API security
context and
provides the
security services
available via the
context
Tool Usage
jar Creates Java Archive (JAR)
files
jarsigner Signs and verifies signatures
on JAR files
keytool Creates and manages key
stores
policytool Creates and edits policy files
for use with default Policy
implementation
There are also three Kerberos-related tools that are shipped with
the Java platform for Windows. Equivalent functionality is
provided in tools of the same name that are automatically part of
the Solaris and Linux operating environments. Table 3
summarizes the Kerberos tools.
Tool Usage
kinit Obtains and caches Kerberos
ticket-granting tickets
klist Lists entries in the local
Kerberos credentials cache
and key table
ktab Manages the names and
service keys stored in the
local Kerberos key table
Introduction
The SunPKCS11 Provider
The SUN Provider
The SunRsaSign Provider
The SunJSSE Provider
The SunJCE Provider
The SunJGSS Provider
The SunSASL Provider
The XMLDSig Provider
The SunPCSC Provider
The SunMSCAPI Provider
Introduction
The Java platform defines a set of APIs spanning major security
areas, including cryptography, public key infrastructure,
authentication, secure communication, and access control. These
APIs allow developers to easily integrate security mechanisms
into their application code. The Java Cryptography Architecture
(JCA) and its Provider Architecture is a core concept of the Java
Development Kit (JDK). It is assumed readers have an solid
understanding of this architecture.
AlgorithmParameters DSA
CertificateFactory X.509
CertPathBuilder PKIX
174
CertStore
Collection
LDAP
Configuration JavaLoginConfig
KeyFactory DSA
KeyPairGenerator DSA
KeyStore JKS
MD2
MD5
MessageDigest
SHA-1
SHA-256
SHA-384
SHA-512
Policy JavaPolicy
SecureRandom SHA1PRNG
Signature
NONEwithDSA
SHA1withDSA
Keysize Restrictions
The SUN provider uses the following default keysizes (in bits) and
enforce the following restrictions:
KeyPairGenerator
175
Alg. Default
Restrictions/Comments
Name Keysize
Keysize must be a multiple of 64, ranging
DSA 1024
from 512 to 1024 (inclusive).
AlgorithmParameterGenerator
Alg. Default
Restrictions/Comments
Name Keysize
Keysize must be a multiple of 64, ranging
DSA 1024
from 512 to 1024 (inclusive).
CertificateFactory/CertPathBuilder/ CertPathValidator/CertStore
implementations
Additional details on the SUN provider implementations for
CertificateFactory, CertPathBuilder, CertPathValidator and
CertStore are documented in Appendix B of the PKI Programmer's
Guide.
Keysize Restrictions
The SunRsaSign provider uses the following default keysizes (in
bits) and enforce the following restrictions:
KeyPairGenerator
Alg. Default
Restrictions/Comments
Name Keysize
Keysize must range between 512 and
RSA 1024 65536 bits, the former of which is
unnecessarily large.
SSLContext
SSLv3
TLSv1
TrustManagerFactory PKIX
Protocol
SSLv3
TLSv1
SSLv2Hello
Supported In Releases
Cipher Suite
178
SSL_RSA_WITH_RC4_128_MD5 X X X X
SSL_RSA_WITH_RC4_128_SHA X X X X
TLS_RSA_WITH_AES_128_CBC_SHA X X X
TLS_RSA_WITH_AES_256_CBC_SHA X X X
TLS_ECDH_ECDSA_WITH_RC4_128_SHA X
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA X
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA X
TLS_ECDH_RSA_WITH_RC4_128_SHA X
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA X
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA X
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA X
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA X
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA X
TLS_ECDHE_RSA_WITH_RC4_128_SHA X
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA X
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA X
TLS_DHE_RSA_WITH_AES_128_CBC_SHA X X X
TLS_DHE_RSA_WITH_AES_256_CBC_SHA X X X
TLS_DHE_DSS_WITH_AES_128_CBC_SHA X X X
TLS_DHE_DSS_WITH_AES_256_CBC_SHA X X X
SSL_RSA_WITH_3DES_EDE_CBC_SHA X X X X
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA X
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA X
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA X
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA X
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA X X X
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA X X X X
SSL_RSA_WITH_DES_CBC_SHA X X X X
SSL_DHE_RSA_WITH_DES_CBC_SHA X X X
SSL_DHE_DSS_WITH_DES_CBC_SHA X X X X
179
SSL_RSA_EXPORT_WITH_RC4_40_MD5 X X X X
SSL_RSA_EXPORT_WITH_DES40_CBC_SHA X X X
SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA X X X
SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA X X X X
SSL_RSA_WITH_NULL_MD5 X X X X
SSL_RSA_WITH_NULL_SHA X X X X
TLS_ECDH_ECDSA_WITH_NULL_SHA X
TLS_ECDH_RSA_WITH_NULL_SHA X
TLS_ECDHE_ECDSA_WITH_NULL_SHA X
TLS_ECDHE_RSA_WITH_NULL_SHA X
SSL_DH_anon_WITH_RC4_128_MD5 X X X X
TLS_DH_anon_WITH_AES_128_CBC_SHA X X X
TLS_DH_anon_WITH_AES_256_CBC_SHA X X X
SSL_DH_anon_WITH_3DES_EDE_CBC_SHA X X X X
SSL_DH_anon_WITH_DES_CBC_SHA X X X X
TLS_ECDH_anon_WITH_RC4_128_SHA X
TLS_ECDH_anon_WITH_AES_128_CBC_SHA X
TLS_ECDH_anon_WITH_AES_256_CBC_SHA X
TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA X
SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 X X X X
SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA X X X X
TLS_ECDH_anon_WITH_NULL_SHA X
TLS_KRB5_WITH_RC4_128_SHA X X
TLS_KRB5_WITH_RC4_128_MD5 X X
TLS_KRB5_WITH_3DES_EDE_CBC_SHA X X
TLS_KRB5_WITH_3DES_EDE_CBC_MD5 X X
TLS_KRB5_WITH_DES_CBC_SHA X X
TLS_KRB5_WITH_DES_CBC_MD5 X X
TLS_KRB5_EXPORT_WITH_RC4_40_SHA X X
TLS_KRB5_EXPORT_WITH_RC4_40_MD5 X X
180
TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA X X
TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 X X
AES
Blowfish
DES
DESede
DiffieHellman
meters OAEP
PBEWithMD5AndDES
PBEWithMD5AndTripleDES
PBEWithSHA1AndDESede
PBEWithSHA1AndRC2_40
RC2
Keysize Restrictions
The SunJCE provider uses the following default keysizes (in bits)
and enforce the following restrictions:
KeyGenerator
184
Default
Alg. Name Restrictions/Comments
Keysize
Keysize must be equal to 128,
AES 128
192, or 256.
ARCFOUR Keysize must range between 40
128
(RC4) and 1024 (inclusive).
Keysize must be a multiple of 8,
Blowfish 128 ranging from 32 to 448
(inclusive).
DES 56 Keysize must be equal to 56.
Keysize must be equal to 112 or
168.
Default
Alg. Name Restrictions/Comments
Keysize
Keysize must range between 40
RC2 128
and 1024 (inclusive).
KeyPairGenerator
Alg. Default
Restrictions/Comments
Name Keysize
Diffie-
Keysize must be a multiple of 64,
Hellman 1024
ranging from 512 to 1024 (inclusive).
(DH)
AlgorithmParameterGenerator
Alg. Default
Restrictions/Comments
Name Keysize
Diffie-
Keysize must be a multiple of 64,
Hellman 1024
ranging from 512 to 1024 (inclusive).
(DH)
Keysize must be a multiple of 64,
DSA 1024
ranging from 512 to 1024 (inclusive).
OID Name
1.2.840.113554.1.2.2 Kerberos v5
1.3.6.1.5.5.2 SPNEGO
Windows-ROOT
Keysize Restrictions
The SunMSCAPI provider uses the following default keysizes (in
bits) and enforce the following restrictions:
KeyGenerator
Alg. Default
Restrictions/Comments
Name Keysize
Keysize ranges from 384 bits to 16,384
bits (depending on the underlying
RSA 1024
Microsoft Windows cryptographic service
provider).
190