Sunteți pe pagina 1din 92

UNIT I

Networking Basics Computers running on the Internet communicate to each other using either the Transmission Control Protocol (TCP) or the User Datagram Protocol (UDP), as this diagram illustrates:

When you write Java programs that communicate over the network, you are programming at the application layer. Typically, you don't need to concern yourself with the TCP and UDP layers. Instead, you can use the classes in the java.net package. These classes provide system-independent network communication. However, to decide which Java classes your programs should use, you do need to understand how TCP and UDP differ. TCP When two applications want to communicate to each other reliably, they establish a connection and send data back and forth over that connection. This is analogous to making a telephone call. If you want to speak to Aunt Beatrice in Kentucky, a connection is established when you dial her phone number and she answers. You send data back and forth over the connection by speaking to one another over the phone lines. Like the phone company, TCP guarantees that data sent from one end of the connection actually gets to the other end and in the same order it was sent. Otherwise, an error is reported. TCP provides a point-to-point channel for applications that require reliable communications. The Hypertext Transfer Protocol (HTTP), File Transfer Protocol (FTP), and Telnet are all examples of applications that require a reliable communication channel. The order in which the data is sent and received over the network is critical to the success of these applications. When HTTP is used to read from a URL, the data must be received in the order in which it was sent. Otherwise, you end up with a jumbled HTML file, a corrupt zip file, or some other invalid information. Definition: TCP (Transmission Control Protocol) is a connection-based protocol that provides a reliable flow of data between two computers. UDP The UDP protocol provides for communication that is not guaranteed between two applications on the network. UDP is not connection-based like TCP. Rather, it sends independent packets of data, called datagrams, from one application to another. Sending datagrams is much like sending a letter through the

postal service: The order of delivery is not important and is not guaranteed, and each message is independent of any other. Definition: UDP (User Datagram Protocol) is a protocol that sends independent packets of data, called datagrams, from one computer to another with no guarantees about arrival. UDP is not connection-based like TCP. For many applications, the guarantee of reliability is critical to the success of the transfer of information from one end of the connection to the other. However, other forms of communication don't require such strict standards. In fact, they may be slowed down by the extra overhead or the reliable connection may invalidate the service altogether. Consider, for example, a clock server that sends the current time to its client when requested to do so. If the client misses a packet, it doesn't really make sense to resend it because the time will be incorrect when the client receives it on the second try. If the client makes two requests and receives packets from the server out of order, it doesn't really matter because the client can figure out that the packets are out of order and make another request. The reliability of TCP is unnecessary in this instance because it causes performance degradation and may hinder the usefulness of the service. Another example of a service that doesn't need the guarantee of a reliable channel is the ping command. The purpose of the ping command is to test the communication between two programs over the network. In fact, ping needs to know about dropped or out-of-order packets to determine how good or bad the connection is. A reliable channel would invalidate this service altogether. The UDP protocol provides for communication that is not guaranteed between two applications on the network. UDP is not connection-based like TCP. Rather, it sends independent packets of data from one application to another. Sending datagrams is much like sending a letter through the mail service: The order of delivery is not important and is not guaranteed, and each message is independent of any others. Note: Many firewalls and routers have been configured not to allow UDP packets. If you're having trouble connecting to a service outside your firewall, or if clients are having trouble connecting to your service, ask your system administrator if UDP is permitted. Understanding Ports Generally speaking, a computer has a single physical connection to the network. All data destined for a particular computer arrives through that connection. However, the data may be intended for different applications running on the computer. So how does the computer know to which application to forward the data? Through the use of ports. Data transmitted over the Internet is accompanied by addressing information that identifies the computer and the port for which it is destined. The computer is identified by its 32-bit IP address, which IP uses to deliver data to the right computer on the network. Ports are identified by a 16-bit number, which TCP and UDP use to deliver the data to the right application. In connection-based communication such as TCP, a server application binds a socket to a specific port number. This has the effect of registering the server with the system to receive all data destined for that port. A client can then rendezvous with the server at the server's port, as illustrated here:

Definition: The TCP and UDP protocols use ports to map incoming data to a particular process running on a computer. In datagram-based communication such as UDP, the datagram packet contains the port number of its destination and UDP routes the packet to the appropriate application, as illustrated in this figure:

Port numbers range from 0 to 65,535 because ports are represented by 16-bit numbers. The port numbers ranging from 0 - 1023 are restricted; they are reserved for use by well-known services such as HTTP and FTP and other system services. These ports are called well-known ports. Your applications should not attempt to bind to them. What Is a Socket? A socket is one end-point of a two-way communication link between two programs running on the network. Socket classes are used to represent the connection between a client program and a server program. The java.net package provides two classes--Socket and ServerSocket--that implement the client side of the connection and the server side of the connection, respectively. Normally, a server runs on a specific computer and has a socket that is bound to a specific port number. The server just waits, listening to the socket for a client to make a connection request. On the client-side: The client knows the hostname of the machine on which the server is running and the port number on which the server is listening. To make a connection request, the client tries to rendezvous with the server on the server's machine and port. The client also needs to identify itself to the server so it binds to a local port number that it will use during this connection. This is usually assigned by the system.

If everything goes well, the server accepts the connection. Upon acceptance, the server gets a new socket bound to the same local port and also has its remote endpoint set to the address and port of the client. It needs a new socket so that it can continue to listen to the original socket for connection requests while tending to the needs of the connected client.

On the client side, if the connection is accepted, a socket is successfully created and the client can use the socket to communicate with the server. The client and server can now communicate by writing to or reading from their sockets. Definition: A socket is one endpoint of a two-way communication link between two programs running on the network. A socket is bound to a port number so that the TCP layer can identify the application that data is destined to be sent. An endpoint is a combination of an IP address and a port number. Every TCP connection can be uniquely identified by its two endpoints. That way you can have multiple connections between your host and the server. The java.net package in the Java platform provides a class, Socket, that implements one side of a two-way connection between your Java program and another program on the network. The Socket class sits on top of a platform-dependent implementation, hiding the details of any particular system from your Java program. By using the java.net.Socket class instead of relying on native code, your Java programs can communicate over the network in a platform-independent fashion. Additionally, java.net includes the ServerSocket class, which implements a socket that servers can use to listen for and accept connections to clients. This lesson shows you how to use the Socket and ServerSocket classes. If you are trying to connect to the Web, the URL class and related classes (URLConnection, URLEncoder) are probably more appropriate than the socket classes. In fact, URLs are a relatively high-level connection to the Web and use sockets as part of the underlying implementation. See Working with URLs for information about connecting to the Web via URLs. Reading from and Writing to a Socket Let's look at a simple example that illustrates how a program can establish a connection to a server program using the Socket class and then, how the client can send data to and receive data from the server through the socket. The example program implements a client, EchoClient, that connects to the Echo server. The Echo server simply receives data from its client and echoes it back. The Echo server is a well-known service that clients can rendezvous with on port 7. EchoClient creates a socket thereby getting a connection to the Echo server. It reads input from the user on the standard input stream, and then forwards that text to the Echo server by writing the text to the socket. The server echoes the input back through the socket to the client. The client program reads and displays the data passed back to it from the server:

import java.io.*; import java.net.*; public class EchoClient { public static void main(String[] args) throws IOException { Socket echoSocket = null; PrintWriter out = null; BufferedReader in = null; try { echoSocket = new Socket("taranis", 7); out = new PrintWriter(echoSocket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader( echoSocket.getInputStream())); } catch (UnknownHostException e) { System.err.println("Don't know about host: taranis."); System.exit(1); } catch (IOException e) { System.err.println("Couldn't get I/O for " + "the connection to: taranis."); System.exit(1); } BufferedReader stdIn = new BufferedReader( new InputStreamReader(System.in)); String userInput; while ((userInput = stdIn.readLine()) != null) { out.println(userInput); System.out.println("echo: " + in.readLine()); } out.close(); in.close(); stdIn.close(); echoSocket.close(); } } Note that EchoClient both writes to and reads from its socket, thereby sending data to and receiving data from the Echo server. Let's walk through the program and investigate the interesting parts. The three statements in the try block of the main method are critical. These lines establish the socket connection between the client and the server and open a PrintWriter and a BufferedReader on the socket: echoSocket = new Socket("taranis", 7); out = new PrintWriter(echoSocket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader( echoSocket.getInputStream()));

The first statement in this sequence creates a new Socket object and names it echoSocket. The Socket constructor used here requires the name of the machine and the port number to which you want to connect. The example program uses the host name taranis. This is the name of a hypothetical machine on our local network. When you type in and run this program on your machine, change the host name to the name of a machine on your network. Make sure that the name you use is the fully qualified IP name of the machine to which you want to connect. The second argument is the port number. Port number 7 is the port on which the Echo server listens. The second statement gets the socket's output stream and opens a PrintWriter on it. Similarly, the third statement gets the socket's input stream and opens a BufferedReader on it. The example uses readers and writers so that it can write Unicode characters over the socket. To send data through the socket to the server, EchoClient simply needs to write to the PrintWriter. To get the server's response, EchoClient reads from the BufferedReader. The rest of the program achieves this. If you are not yet familiar with the Java platform's I/O classes, you may wish to read Basic I/O. The next interesting part of the program is the while loop. The loop reads a line at a time from the standard input stream and immediately sends it to the server by writing it to the PrintWriter connected to the socket: String userInput; while ((userInput = stdIn.readLine()) != null) { out.println(userInput); System.out.println("echo: " + in.readLine()); } The last statement in the while loop reads a line of information from the BufferedReader connected to the socket. The readLine method waits until the server echoes the information back to EchoClient. When readline returns, EchoClient prints the information to the standard output. The while loop continues until the user types an end-of-input character. That is, EchoClient reads input from the user, sends it to the Echo server, gets a response from the server, and displays it, until it reaches the end-of-input. The while loop then terminates and the program continues, executing the next four lines of code: out.close(); in.close(); stdIn.close(); echoSocket.close(); These lines of code fall into the category of housekeeping. A well-behaved program always cleans up after itself, and this program is well-behaved. These statements close the readers and writers connected to the socket and to the standard input stream, and close the socket connection to the server. The order here is important. You should close any streams connected to a socket before you close the socket itself. This client program is straightforward and simple because the Echo server implements a simple protocol. The client sends text to the server, and the server echoes it back. When your client programs are talking to a more complicated server such as an HTTP server, your client program will also be more complicated. However, the basics are much the same as they are in this program: 1. Open a socket. 2. Open an input stream and output stream to the socket.

3. Read from and write to the stream according to the server's protocol. 4. Close the streams. 5. Close the socket. Only step 3 differs from client to client, depending on the server. The other steps remain largely the same. UDP Some applications that you write to communicate over the network will not require the reliable, point-topoint channel provided by TCP. Rather, your applications might benefit from a mode of communication that delivers independent packages of information whose arrival and order of arrival are not guaranteed. The UDP protocol provides a mode of network communication whereby applications send packets of data, called datagrams, to one another. A datagram is an independent, self-contained message sent over the network whose arrival, arrival time, and content are not guaranteed. The DatagramPacket and DatagramSocket classes in the java.net package implement system-independent datagram communication using UDP. What Is a Datagram? Clients and servers that communicate via a reliable channel, such as a TCP socket, have a dedicated point-to-point channel between themselves, or at least the illusion of one. To communicate, they establish a connection, transmit the data, and then close the connection. All data sent over the channel is received in the same order in which it was sent. This is guaranteed by the channel. In contrast, applications that communicate via datagrams send and receive completely independent packets of information. These clients and servers do not have and do not need a dedicated point-to-point channel. The delivery of datagrams to their destinations is not guaranteed. Nor is the order of their arrival. Definition: A datagram is an independent, self-contained message sent over the network whose arrival, arrival time, and content are not guaranteed. The java.net package contains three classes to help you write Java programs that use datagrams to send and receive packets over the network: DatagramSocket, DatagramPacket, and MulticastSocketAn application can send and receive DatagramPackets through a DatagramSocket. In addition, DatagramPackets can be broadcast to multiple recipients all listening to a MulticastSocket. Writing a Datagram Client and Server The example featured in this section consists of two applications: a client and a server. The server continuously receives datagram packets over a datagram socket. Each datagram packet received by the server indicates a client request for a quotation. When the server receives a datagram, it replies by sending a datagram packet that contains a one-line "quote of the moment" back to the client. The client application in this example is fairly simple. It sends a single datagram packet to the server indicating that the client would like to receive a quote of the moment. The client then waits for the server to send a datagram packet in response.

Two classes implement the server application: QuoteServer and QuoteServerThread. A single class implements the client application: QuoteClient. Let's investigate these classes, starting with the class that contains the main method for the server application. Working With a Server-Side Application contains an applet version of the QuoteClient class. The QuoteServer Class The QuoteServer class, shown here in its entirety, contains a single method: the main method for the quote server application. The main method simply creates a new QuoteServerThread object and starts it: import java.io.*; public class QuoteServer { public static void main(String[] args) throws IOException { new QuoteServerThread().start(); } } The QuoteServerThread class implements the main logic of the quote server. The QuoteServerThread Class When created, the QuoteServerThread creates a DatagramSocket on port 4445 (arbitrarily chosen). This is the DatagramSocket through which the server communicates with all of its clients. public QuoteServerThread() throws IOException { this("QuoteServer"); } public QuoteServerThread(String name) throws IOException { super(name); socket = new DatagramSocket(4445); try { in = new BufferedReader( new FileReader("one-liners.txt")); } catch (FileNotFoundException e) System.err.println("Couldn't open quote file. " + "Serving time instead."); } } Remember that certain ports are dedicated to well-known services and you cannot use them. If you specify a port that is in use, the creation of the DatagramSocket will fail. The constructor also opens a BufferedReader on a file named one-liners.txt which contains a list of quotes. Each quote in the file is on a line by itself. Now for the interesting part of the QuoteServerThread: its run method. The run method overrides run in the Thread class and provides the implementation for the thread. For information about threads, see Defining and Starting a Thread. The run method contains a while loop that continues as long as there are more quotes in the file. During each iteration of the loop, the thread waits for a DatagramPacket to arrive over the DatagramSocket. The packet indicates a request from a client. In response to the client's request, the QuoteServerThread gets a quote from the file, puts it in a DatagramPacket and sends it over the DatagramSocket to the client that asked for it. Let's look first at the section that receives the requests from clients: byte[] buf = new byte[256]; DatagramPacket packet = new DatagramPacket(buf, buf.length);

socket.receive(packet); The first statement creates an array of bytes which is then used to create a DatagramPacket. The DatagramPacket will be used to receive a datagram from the socket because of the constructor used to create it. This constructor requires only two arguments: a byte array that contains client-specific data and the length of the byte array. When constructing a DatagramPacket to send over the DatagramSocket, you also must supply the Internet address and port number of the packet's destination. You'll see this later when we discuss how the server responds to a client request. The last statement in the previous code snippet receives a datagram from the socket (the information received from the client gets copied into the packet). The receive method waits forever until a packet is received. If no packet is received, the server makes no further progress and just waits. Now assume that, the server has received a request from a client for a quote. Now the server must respond. This section of code in the run method constructs the response: String dString = null; if (in == null) dString = new Date().toString(); else dString = getNextQuote(); buf = dString.getBytes(); If the quote file did not get opened for some reason, then in equals null. If this is the case, the quote server serves up the time of day instead. Otherwise, the quote server gets the next quote from the already opened file. Finally, the code converts the string to an array of bytes. Now, the run method sends the response to the client over the DatagramSocket with this code: InetAddress address = packet.getAddress(); int port = packet.getPort(); packet = new DatagramPacket(buf, buf.length, address, port); socket.send(packet); The first two statements in this code segment get the Internet address and the port number, respectively, from the datagram packet received from the client. The Internet address and port number indicate where the datagram packet came from. This is where the server must send its response. In this example, the byte array of the datagram packet contains no relevant information. The arrival of the packet itself indicates a request from a client that can be found at the Internet address and port number indicated in the datagram packet. The third statement creates a new DatagramPacket object intended for sending a datagram message over the datagram socket. You can tell that the new DatagramPacket is intended to send data over the socket because of the constructor used to create it. This constructor requires four arguments. The first two arguments are the same required by the constructor used to create receiving datagrams: a byte array containing the message from the sender to the receiver and the length of this array. The next two arguments are different: an Internet address and a port number. These two arguments are the complete address of the destination of the datagram packet and must be supplied by the sender of the datagram. The last line of code sends the DatagramPacket on its way. When the server has read all the quotes from the quote file, the while loop terminates and the run method cleans up: socket.close();

The QuoteClient Class The QuoteClient class implements a client application for the QuoteServer. This application sends a request to the QuoteServer, waits for the response, and, when the response is received, displays it to the standard output. Let's look at the code in detail.

The QuoteClient class contains one method, the main method for the client application. The top of the main method declares several local variables for its use: int port; InetAddress address; DatagramSocket socket = null; DatagramPacket packet; byte[] sendBuf = new byte[256]; First, the main method processes the command-line arguments used to invoke the QuoteClient application: if (args.length != 1) { System.out.println("Usage: java QuoteClient <hostname>"); return; } The QuoteClient application requires one command-line arguments: the name of the machine on which the QuoteServer is running. Next, the main method creates a DatagramSocket: DatagramSocket socket = new DatagramSocket(); The client uses a constructor that does not require a port number. This constructor just binds the
DatagramSocket to any available local port. It doesn't matter what port the client is bound to because the DatagramPackets contain the addressing information. The server gets the port number from the DatagramPackets and send its response to that port.

Next, the QuoteClient program sends a request to the server: byte[] buf = new byte[256]; InetAddress address = InetAddress.getByName(args[0]); DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 4445); socket.send(packet); The code segment gets the Internet address for the host named on the command line (presumably the name of the machine on which the server is running). This InetAddress and the port number 4445 (the port number that the server used to create its DatagramSocket) are then used to create DatagramPacket destined for that Internet address and port number. Therefore the DatagramPacket will be delivered to the quote server. Note that the code creates a DatagramPacket with an empty byte array. The byte array is empty because this datagram packet is simply a request to the server for information. All the server needs to know to send a response--the address and port number to which reply--is automatically part of the packet. Next, the client gets a response from the server and displays it: packet = new DatagramPacket(buf, buf.length); socket.receive(packet); String received = new String(packet.getData(), 0, packet.getLength()); System.out.println("Quote of the Moment: " + received); To get a response from the server, the client creates a "receive" packet and uses the DatagramSocket receive method to receive the reply from the server. The receive method waits until a datagram packet destined for the client comes through the socket. Note that if the server's reply is somehow lost, the client will wait forever because of the no-guarantee policy of the datagram model. Normally, a client sets a timer so that it doesn't wait forever for a reply; if no reply arrives, the timer goes off and the client retransmits. When the client receives a reply from the server, the client uses the getData method to retrieve that data from the packet. The client then converts the data to a string and displays it.

Running the Server and Client After you've successfully compiled the server and the client programs, you run them. You have to run the server program first. Just use the Java interpreter and specify the QuoteServer class name. Once the server has started, you can run the client program. Remember to run the client program with one command-line argument: the name of the host on which the QuoteServer is running. After the client sends a request and receives a response from the server, you should see output similar to this: Quote of the Moment: - Good programming is 99% sweat and 1% coffee.

RMI Distributed Systems: running programs in different hosts (address spaces) that communicate Sockets: basic communication mechanism; needs protocols for exchanged message encoding and decoding (in clients and servers); error prone; cumbersome design Remote Procedure Call (RPC): easier than sockets; uses external data representation for parameters passed and returned values Distributed Object Systems: need to deal with communication between program level objects in different address spaces Remote Method Invocation (RMI): uses local surrogate object (stub) to manages remote object invocation (via rmiregistry and remote interfaces) RMI: Java RMI Java RMI: uses the homogeneous environment of Java Virtual Machine (JVM)to provide the communication mechanism: o Locate remote objects: register remote objects with RMI naming facility (rmiregistry); pass and return remote object references o Communicate with remote objects: Java method call handling by RMI o Load class bytecodes for objects passed as parameters or return values:load object code, transmit its data Communication between Servers and Clients: communicate references to remote objects (parameters, results); non-remote arguments copied across Server: create remote objects; make references to them accessible; wait for clients to invoke the remote object methods

Client: get remote references to remote objects on server; invoke methods on them

Exceptions: problems with remote invocation RMI: Java RMI Registry mechanism Server calls registry: name associated with a remote object Client looks up the remote object by name: name found in server's registry then a method called Classbytes loaded from Server to Client: Server class file copied to client webserver Classbytes loaded from Client to Server: Client class file copied to server webserver RMI 1: Interfaces & Classes java.rmi.Remote interface: a remote interface extends it java.rmi.RemoteException: every method in the remote interface throws this exception java.rmi.server.RemoteObject java.rmi.server.RemoteServer

java.rmi.server.UnicastRemoteObject java.rmi.activation.Activatable extend & implement: classes implement the remote interface methods; stubs are generated by the rmic compiler and are passed instead of the implementing objects to the remote hosts Serializable: objects serialised before being passed by value java.io.Serializable Dynamic Class Loading: bytecode of object classes down-loaded from one host to another as and when needed RMI Example: Remote Interface Remote Compute Interface /** * compute/Compute.java * Remote Interface **/ package compute;

import java.rmi.Remote; import java.rmi.RemoteException;

public interface Compute extends Remote{ Object executeTask(Task t) throws RemoteException; } RMI 2: Stubs & Skeletons Stub: client's proxy for remote object Skeleton: server's interface for its remote object rmic: compiler for generating stubs & skeletons RMI 2.1: Stubs method call Stub method call 1. initiates the connection to remote VM containing the remote object 2. marshals (write & transmit) the parameters to the remote objet 3. waits for the result of the method invocation 4. unmarshals (read) the return value or exception returned 5. returns the value to the caller Serialization of parameters and network-level communication hidden RMI 2.2: Skeleton Skeleton handles incoming method invocation as follows: 1. unmarshals (reads) the parameters for the remote method 2. invokes the method on the actual remote object implementation 3. marshals (write & transmit) the result (return value or exception) to the caller JDK1.2 only environment works without skeletons, using additional stub protocols to execute generic codes that perform the work of skeletons. RMI 3: Garbage Collection of Remote Objects Automatic deletion of remote objects no longer referenced by a client

Reference Counting GC: RMI runtime keeps track of the live references to each remote object, incrementing a reference count for a new live reference and decrementing it when a live reference is unreferenced. When a remote object receives its first live reference it is signalled as ``referenced'' to the server for the object. When no live references to the object exist it is signalled as ``unreferenced'' to the server of the object. Java virtual machine garbage collector will take care of such ``unreferenced'' objects. What Is a Servlet?
A servlet is a Java programming language class used to extend the capabilities of servers that host applications accessed via a request-response programming model. Although servlets can respond to any type of request, they are commonly used to extend the applications hosted by Web servers. For such applications, Java Servlet technology defines HTTP-specific servlet classes. The javax.servlet and javax.servlet.http packages provide interfaces and classes for writing servlets. All servlets must implement the Servlet interface, which defines life-cycle methods. When implementing a generic service, you can use or extend the GenericServlet class provided with the Java Servlet API. The HttpServlet class provides methods, such as doGet and doPost, for handling HTTP-specific services. This chapter focuses on writing servlets that generate responses to HTTP requests. Some knowledge of the HTTP protocol is assumed; if you are unfamiliar with this protocol, you can get a brief introduction to HTTP. Servlet Life Cycle Before start writing the servlet, it is important to know the life cylce of every servlet instance created. Read What is Servlet? tips to know about the servlet basics. Servlet Life Cycle Methods The following are the life cycle methods of a servlet instance: init() service() destroy() We will look into the each method in detail. init() This method is called once for a servlet instance. When first time servlet is called, servlet container creates instance of that servlet and loaded into the memory. Future requests will be served by the same instance without creating the new instance. Servlet by default multithreaded application.init() method is used for inilializing servlet variables which are required to be passed from the deployment descriptor web.xml. ServletConfig is passed as the parameter to init() method which stores all the values configured in the web.xml. It is more convenient way to initialize the servlet. service() This method is called for the each request. This is the entry point for the every servlet request and here we have to write our businesslogic or any other processes. This method takes HttpServletRequest and HttpServletresponse as the parameters. It is not mandatory to write this method, normally developers are interested in writing doGet() or doPost() methods which is by default called from the service() method. If

you override service(), it is your reponsibility to call the appropriate methods. If you are not overridden the service() method, based on the types of the request the methods will be called. destroy() This method will be called once for a instance. It is used for releasing any resources used by the servlet instance. Most of the times it could be database connections, Fill IO operations, etc. destroy() is called by the container when it is removing the instance from the servlet container. Servlet instance is deleted or garbage collected by the container only when the web server issues shut down or the instance is not used for a long time. BookDetailsServlet generates a page that looks like Figure 10-2.

Servlet Life Cycle The life cycle of a servlet is controlled by the container in which the servlet has been deployed. When a request is mapped to a servlet, the container performs the following steps. 1. If an instance of the servlet does not exist, the Web container a. Loads the servlet class. b. Creates an instance of the servlet class. c. Initializes the servlet instance by calling the init method. Initialization is covered in Initializing a Servlet. 2. Invokes the service method, passing a request and response object. Service methods are discussed in the section Writing Service Methods. If the container needs to remove the servlet, it finalizes the servlet by calling the servlet's destroy method. Finalization is discussed in Finalizing a Servlet. Handling Servlet Life-Cycle Events You can monitor and react to events in a servlet's life cycle by defining listener objects whose methods get invoked when life cycle events occur. To use these listener objects, you must define the listener class and specify the listener class. Defining The Listener Class You define a listener class as an implementation of a listener interface. Table 10-3 lists the events that can be monitored and the corresponding interface that must be implemented. When a listener method is invoked, it is passed an event that contains information appropriate to the event. For example, the

methods in the HttpSessionListener interface are passed an HttpSessionEvent, which contains an HttpSession. Table 10-3 Servlet Life-Cycle Events Object Event Initialization and destruction Web context (See Accessing the Web Context) Attribute added, removed, or replaced Creation, invalidation, and timeout Session (See Maintaining Client State) Attribute added, removed, or replaced Listener Interface and Event Class javax.servlet.ServletContextListener and ServletContextEvent javax.servlet.ServletContextAttributeListener and ServletContextAttributeEvent javax.servlet.http.HttpSessionListener and HttpSessionEvent javax.servlet.http.HttpSessionAttributeListener and HttpSessionBindingEvent

The listeners.ContextListener class creates and removes the database helper and counter objects used in the Duke's Bookstore application. The methods retrieve the Web context object from ServletContextEvent and then store (and remove) the objects as servlet context attributes. import database.BookDB; import javax.servlet.*; import util.Counter; public final class ContextListener implements ServletContextListener { private ServletContext context = null; public void contextInitialized(ServletContextEvent event) { context = event.getServletContext(); try { BookDB bookDB = new BookDB(); context.setAttribute("bookDB", bookDB); } catch (Exception ex) { System.out.println( "Couldn't create database: " + ex.getMessage()); } Counter counter = new Counter(); context.setAttribute("hitCounter", counter); context.log("Created hitCounter" + counter.getCounter()); counter = new Counter(); context.setAttribute("orderCounter", counter); context.log("Created orderCounter" + counter.getCounter()); }

public void contextDestroyed(ServletContextEvent event) { context = event.getServletContext(); BookDB bookDB = context.getAttribute( "bookDB"); bookDB.remove(); context.removeAttribute("bookDB"); context.removeAttribute("hitCounter"); context.removeAttribute("orderCounter"); } } Handling Errors Any number of exceptions can occur when a servlet is executed. The Web container will generate a default page containing the message A Servlet Exception Has Occurred when an exception occurs, but you can also specify that the container should return a specific error page for a given exception. You specify error pages for a WAR in the deploytool File Refs inspector (see Error Mapping). JSP Introduction In this JSP tutorial, you will learn about JSP, usage of JSP, process of development, independency of layers and simplification of process. Usage of JSP: 1. JSP is widely used for developing dynamic web sites. 2. JSP is used for creating database driven web applications because it provides superior server side scripting support. Some of the reasons for the popularity of JSP are Simplifies the process of development: It allows programmers to insert the Java code directly into the JSP file, making the development process easier. Although JSP files are HTML files, they use special tags containing the Java source code which provides a dynamic ability. Portability: The Java feature of write once, run anywhere is applicable to JSP. JSP is platform independent, making it portable across any platform and therefore, mulit-platform. It is possible for the programmer to take a JSP file and move it to another platform, JSP Servlet engine or web server. Because of Efficiency : As soon as the request is received, the JSP pages gets loaded into the web servers memory. The following transactions are then carried out within a minimal time period, handling JSP pages with efficiency. Reusability: JSP allow component reuse by using JavaBeans and EJBs.

Robust: JSP offers a robust platform for web development Independency of Layers: There is a clear separation between presentation and implementation layers. The HTML on the web browser of the client is displayed as a presentation layer. The JSP on the server is displayed in the implementation layer. Programmers who want to work with HTML can work independently without the work of the Java developers, working in the implementation layer, being affected. Java Server Pages, or JSP, is the way to separate the look of the web page from the corresponding content. Integration of JSP with Other source like JDBC, Servlet and so on: The combination of JDBC and JSP works very well. JSP is used for generating dynamic web pages. It is essential that data in these systems be maintained efficiently and securely. The programmer must have a good database and database connectivity. This is achieved by JDBC through its excellent database connectivity in heterogeneous database system. This database system is used for the integration of heterogeneous database management systems presenting a single query interface system. Simplification of Process: The JSP language has a simple development and maintenance process. A JSP file that has the extension .jsp is converted into a servlet .java which is dynamically compiled, loaded and executed. Only when there is a change in a JSP file, the Conversion, compilation, and loading process is then performed. A Servlet is a Java class that is used to handle server side service. Though it is possible to write HTML code in servlet, it would require a great deal of statements for a programmer to achieve the same results as JSP. JSP handles HTML easily and converts to Servlets, enabling the functionality and features of servlet in addition to its own special features. Technically speaking, the source code of JSP runs in the JSP Servlet Engine on the web server. This JSP Servlet engine generates the HTML dynamically, displaying the output directly to the web browser of the client JSP Environment Setup : Steps for Setting JSP Environment In this JSP tutorial, you will learn the steps for setting JSP environment in Microsoft Windows, setting the PATH and CLASSPATH, steps for downloading and installing the Tomcat web server. The Java Server Page or JSP is very affordable as most of the software needed for it is easily available for free or at low cost. 1. The Java Developer Kit which is available for free 2. 3. The Tomcat web server if used is available for free. HTML editor would be needed to purchase.

How to set up the JSP Environment in Microsoft Windows: There are slight differences between operating systems for the JSP Environments set up in Windows but below are the basic steps. First Step: The first and foremost step before setting up the JSP environment is to verify the presence of Java Developer Kit or JDK on the programmers system. If it is not present, the Java Developer Kit or JDK must be downloaded and installed. This link provides the JDK download: http://java.sun.com/j2ee/download.html Or http://java.sun.com/javase/downloads/index.jsp This link provides the latest Windows Platform version of Java SDK. Second Step: After the download, the next step is to run the executable setup, or the exe, and follow the prompted instructions on screen. Third Step: Setting the PATH and CLASSPATH: The third step is to set the PATH and CLASSPATH. In Windows 95 or Windows 98, edit the AUTOEXEC.BAT file. In this file, the user has to add the directory <JDK installation directory>bin to the PATH setting in the autoexec.bat file. The above sets the new PATH. Set the CLASSPATH in a similar manner by adding the path <JDK installation directory>libj2ee.jar to the CLASSPATH setting in the autoexec.bat file. The above steps define new PATH and CLASSPATH settings. If the system is Windows 2000 or Windows XP, edit the environment variables to set the PATH and CLASSPATH settings. The environment variables are accessed by navigating as follows: Control Panel -> System -> Environment Variables Repeat the same procedure to set new PATH and CLASSPATH settings. Fourth Step: The machine must be rebooted to enable the new settings. Fifth Step: The JSP environments can be download here : http://java.sun.com/products/jsp/index.jsp. Sixth Step: The next major step is to download and install the Tomcat web server. This is needed if the programmer does not possess a JSP-capable web server installed on their machine. Tomcat, developed by Apache, is a free open source JSP and Servlet engine. Steps for downloading and installing the Tomcat web server: (1) http://jakarta.apache.org/ download the latest version of Tomcat. (2) Unzip the downloaded Tomcat zip files, and any files present in the subdirectories that have been

placed in a single directory, if any. (3) Open the file autoexec.bat file to the entry: SET TOMCAT_HOME=<directory> Where the directory mentioned above would be the directory into which the contents of the .zip file were extracted. If the directory created by the user was exforsys , all the contents of the .zip file were extracted then the user make an entry in autoexec.bat file as follows: SET TOMCAT_HOME=c:exforsys The above process is only for Windows 95 or Windows 98. If using Windows 2000 or Windows XP, the environment variable TOMCAT_HOME can be set as the directory in: c:exforsys (4) The next step is to change the server. Navigate to exforsysbin as seen in the examples above and type startup. (5) The system reboots and opens the web browser. The user types in the address box: http://localhost:8080/ (6) The JSP files written by the user are placed in " webapps" directory, inside the created directory exforsys, using the above example. Using the JSP file, example.jsp, this copies into webapps/ROOT directory. Open the web browser and type in the address box http://localhost:8080/example.jsp ( displays the executed JSP file.) JSP Tags In this JSP tutorial, you will learn about JSP tags, list of the tags used in Java Server Pages, declaration tag, general syntax of declaration tag, expression tag and general syntax of expression tag. Tags are a vital concept in Java Server Pages (JSP). Below is a list of tags used in JSP. This section discusses Declaration Tag and Expression Tag in detail; syntax, usage with examples and explanations for both. List of the tags used in Java Server Pages: 1. Declaration tag 2. Expression tag 3. Directive tag 4. Scriptlet tag 5. Action tag Syntax, usage and example of Declaration Tag and Expression Tag: Declaration tag: Declaration tag is used to define functions, methods and variables that will be used in Java Server Pages. Notation of the Declaration tag is shown below: <%! %>

At the start of Declaration tag one must place <%! Inside Declaration tag one can declare variables or methods. Declaration tag ends with the notation %>. Also care must be taken to place a semicolon that is ; at the end of each code placed inside Declaration tag. General syntax of Declaration Tag: <%! //start of declaration tag statement1; statement2; //variables or methods declaration ..........; ..........; %> For example: <%! private int example = 0 ; private int test = 5 ; %> Expression tag: Expression tag is used to display output of any data on the generated page. The data placed in Expression tag prints on the output stream and automatically converts data into string. The Expression tag can contain any Java expression used for printing output equivalent to out.println().Thus, an expression tag contains a scripting language expression which is evaluated, automatically converts data to a String and the outputs are displayed. Notation of Expression tag is shown below: <%= %> Expression tag must begin with <%= Inside Expression tag, the user embeds any Java expression. Expression tag ends with the notation %>. NOTE: Expression should not contain a semicolon between codes, as with Declaration tag. General syntax of Expression Tag: <%! statement %> For example: <%! //start of declaration tag //Java Expression //end of declaration tag

//end of declaration tag

Exfdate: <%= new java.util.Date() %> %> Above example displays current date and time as Date() is placed inside the Expression tag <%= %> JSP Directives In this JSP tutorial, you will learn about Directive tag with example, page directive, language, extends, import, session and buffer. Directive tag: The directive tag gives special information about the page to JSP Engine. This changes the way JSP Engine processes the page. Using directive tag, user can import packages, define error handling pages or session information of JSP page. General notation of directive tag is as follows: There are three types of directive tag.

page Include Tag Lib

Syntax and usage of directive tag page directive: General syntax for the page directive is : - <%@ page optional attribute ... %> There are many optional attributes available for page directive. Each of these attributes are used to give special processing information to the JSP Engine changing the way the JSP Engine processes the page. Some of the optional attributes available for page directive are:

language extends import session buffer autoFlush isThreadSafe info errorPage IsErrorPage contentType

Syntax and usage of some of the optional attributes available for page directive discussed below.

language: This attribute is used to denote the language used by a file. Language denotes the scripting language used in scriptlets, declarations, and expressions in the JSP page and any included files. Syntax of language attribute available for page directive is :- <%@ page language = "lang" %> In the above statement page and language are keywords and one places whatever language the file uses inside " ". For example if one wants to mention the language as java which is generally mentioned for all it is done as shown below: <%@ page language = "java" %> extends: This is used to signify the fully qualified name of the Super class of the Java class used by the JSP engine for the translated Servlet. Syntax of extends attribute available for page directive is :- <%@ page extends = "package.class"%> In the above statement page and extends are keywords. import: The import attribute is used to import all the classes in a java package into the current JSP page. With this facility, the JSP page can use other java classes. Syntax of import attribute available for page directive is : - <%@ page import = "java.util.*" %> In the above statement page and import are keywords. If there are many Java packages that the JSP page wants to import, the programmer can use import more than once in a JSP page or separate the Java packages with commas, as shown below: <%@ page import="{package.class | package.*}, ..." %> session: The session attribute, when set to true, sets the page to make use of sessions. NOTE: by default, the session attribute value is set to true therefore, all JSP pages have session data available. If the user sets the session attribute to false, it should be performed in this section. When the session attribution is set to false, the user cannot use the session object, or a <jsp:useBean> element with scope=session in the JSP page which, if used, would give error. Syntax of session attribute available for page directive is : <%@ page session="true|false" %> In the above statement page and session are keywords. And either true or false value can be setted and by default the value is true. buffer: If a programmer likes to control the use of buffered output for a JSP page then the buffer attribute can be made use of for achieving this. Syntax of buffer attribute available for page directive is : - <%@ page buffer = "none|8kb|sizekb" %>

In the above statement page and buffer are keywords. The size of buffer size is mentioned in kilobytes. This is used by the out object to handle output sent from the compiled JSP page to the client web browser. The default value is 8kb. If a user specifies a buffer size then the output is buffered with at least the size mentioned by the user. For example one can specify as: <%@ page buffer = "none" %> JSP Page Directive autoFlush: autoFlush attribute is used to specify whether or not to automatically flush out the output buffer when it is full. Syntax of autoFlush attribute available for page directive is written as: &lt;%@ page autoFlush = "true|false" %&gt; In the above example, page and autoFlush are keywords. True or false value can be set to autoFlush attribute, by default, its value is true . This means, the buffer will be flushed automatically when it is full. When the autoflush attribute is set to false, then an exception is thrown when the output buffer gets full and results in overflow. NOTE: The user should not to set the autoflush to false when the buffer attribute is set to none. isThreadSafe: isThreadSafe attribute is used to set whether the generated Servlet handles multiple requests or single requests, depending on the set value of true or false. isThreadSafe attribute is used to set and ensure whether thread safety is implemented in the JSP page. Syntax of isThreadSafe attribute available for page directive is: &lt;%@ page isThreadSafe="true|false" %&gt; In the above statement, page and isThreadSafe are keywords. A true or false value can be set and, by default, the value is set to true. It implies that the JSP container can handle or send multiple concurrent client requests to the JSP page by starting a new thread. If the value of this attribute is set to false, then the JSP container sends client requests only one at a time to the JSP page. info: Programmers make use of info attribute to place the information or documentation for a page. Details such as: author, version, copyright and date are placed in this attribute. This is actually text string that is written as input text in the compiled JSP page.

Syntax of info attribute available for page directive is: &lt;%@ page info = "text" %&gt; In the above statement, page and info are keywords. The details of documentation or information are placed inside " ". This is actually text string written as input text in the compiled JSP page. For example: &lt;%@ page info = "exforsys.com example,2006" %&gt; The above text, exforsys.com example, 2006, is a text string written as text in the compiled JSP page. errorPage: If the programmer wants to place errors in a different page then the URL to the error page can be mentioned in this attribute as errorPage. Syntax of errorPage attribute available for page directive is as below: &lt;%@ page errorPage = "relativeURL" %&gt; In the above statement, page and errorPage are keywords. For example, the user specifies the attribute errorpage is: &lt;%@ page errorPage = "/handleerr/testerr.jsp" %&gt; isErrorPage: isErrorPage attribute is used to specify whether or not a JSP page displays an error page by setting the value as true or false. By default, the value is set to false, meaning that the user cannot make use of the exception object in the JSP page. If the value is set to true, then it means that the user can make use of the exception object in the JSP page. Syntax of isErrorPage attribute available for page directive is: &lt;%@ page isErrorPage="true|false" %&gt; In the above statement, page and isErrorPage are keywords. By default, the value is false. contentType: contentType attribute is used to set the mime type and character set of the JSP. The user can make use of any MIME type or character set valid for the JSP container. Syntax of contentType attribute available for page directive is: &lt;%@ page contentType="mimeType [; charset=characterSet]" %&gt; In the above statement, page and contentType are keywords. The default, MIMEtype is text/html, and the default character set is ISO-8859-1.

For example, the user specifies the attribute contentType is: &lt;%@ page contentType="text/html;charset=ISO-8859-1" %&gt; JSP Directive Tag and Scriptlet tag In this JSP tutorial, you will learn about two types of Directive tag namely Include and Tag Lib and also Scriptlet tag used in Java Server Pages along with syntax, usage, example and explanation for each of the tag. Include directive: Include directive is a type of directive tag. If a programmer wants to include contents of a file inside another, then the Include directive is used. The file included can be either static ( HTML file) or dynamic (i.e., another tag file). The include directive is used to include the contents of other file in the current tag file. Syntax of Include directive is: &lt;%@ include file = "xxx.html/xx.tagf"%&gt; In the above statement, include and file are keywords. This includes either .html (static file) or .tagf file (dynamic file) between " " in the include directive. For instance: &lt;%@ include file = "include/exforsys.html"%&gt; Above example shows how to include a static resource called exforsys.html in an include directive. The above example includes the html from exforsys.html found in the include directory into the current JPS page. For example: The user includes a dynamic file in the include directive: &lt;%@ include file="exforsys.tagf" %&gt; The above example shows how to include a dynamic resource called exforsys.tagf in the include directive. Tag Lib directive: A user can customize actions from their tag file using the Tag Lib directive. The Tag Lib directive is a collection of custom tags. The syntax of Tag Lib directive is:- &lt;%@ taglib uri = "tag library URI" prefix = "tag Prefix" %&gt; In the above, taglib and uri are both keywords. The URI, which can be absolute or relative, uniquely identifies the tag library descriptor and is enclosed with " " in tag library URI. The tag prefix included inside " " is a string that will become the prefix to distinguish a custom action.

If the custom tag has a content body, then the format for using a custom tag in taglib directive is as follows: &lt;prefix:tagName&gt;body&lt;/prefix:tagName&gt; If the custom tag does not have content body, then the format for using a custom tag in taglib directive is as follows: &lt;prefix:tagName/&gt; Scriptlet tag: Scriptlet tag is a type tag used for inserting Java Code into JSP. Notation of the Scriptlet tag is: - &lt;% %&gt; To begin the Scriptlet tag, the user must add &lt;% . Inside the Scriptlet tag, the user can add any valid Scriptlet, meaning any valid Java Code. User can write the code in between the Scriptlet tag accesses any variable or bean declared. The Scriptlet tag ends with the notation %&gt;. NOTE: there must be semicolon ; included at the end of each code inside the Scriptlet tag. General syntax of Scriptlet Tag:

&lt;%! statement1; statement2; //Valid Java Code ..........; ..........; %&gt; For instance //end of Scriptlet tag

&lt;% for (int j = 0; j &lt;5; j++) { out.print(j); %&gt; }

In the above example, the Java code embeds inside the tag &lt;% and %&gt;. NOTE: at the end of the statement, a semicolon ; is appended.

JSP Architecture In this JSP tutorial, you will learn about JSP Architecture, page-centric approach, dispatcher approach and steps in execution of a JSP file. JSP is a high-end technology that helps developers insert java code in HTML pages by making use of special JSP tags. The JSP are HTML pages but do not automatically have .html as file extension. JSP files have .jsp as extension. The following steps takes place in execution of a JSP file. JSP files are compiled by JSP engine into a servlet. This step creates the .jsp file as a Java servlet source file. Once this is processed, the source file above is compiled into a class file. The engine then makes use of the compiled servlet from the above process and executes requests. Out of the two processes, the first two take time to produce a compiled servlet. This is performed only once unless modification in the source file is required. Once the compiled servlet is completed, the execution of requests is performed at a faster speed.

There are two methods for using JSP technology: Page-Centric Approach

Dispatcher Approach

Page-Centric Approach: The page-centric approach is also called Client-Server approach. The basic idea of Client-Server approach is that the application lies on the client side and services the requests connecting to the server application. JSP using this approach-processes as follows: Client makes a request. The JSP page takes the request from client and processes it. The JSP have access to the database by using Java Beans. The requests are processed and the serviced results are sent back to client by JSP.

The above approach has the advantage of simplifying the process but its disadvantage is when the number of clients increases, the process becomes difficult to handle. Dispatcher Approach: This is also called N-tier approach, where the server side of the above architecture is divided into multiple tiers, using JSP as a controller, passing requests to Java Beans. JSP is popular because of its processing ability. Processing is distinctly divided between Presentation and Front Components. The popular JSP Architecture is the Model View Controller (MVC) model. In this MVC model, the request is sent by the browser to the controller or the servlet. This request is instantiated by the servlet as a Java Bean by JSP. The main aspect is JSP are compiled into servlets at the back end and the front end tasks are not interrupted. The servlet engine takes up the responsibility of compiling JSP Servlet and producing the final JSP servlet class for usage. The front end presentation modules are handled by JSP for viewing and the manipulation of data is handled by Java Bean and passed back to JSP when needed. The Presentation part of the MVC Model has no processing logic. It performs the task of extracting beans or objects that may have been initially created by the controller. It also extracts the dynamic content within for insertion within its static templates. The Application Manager in the MVC Model is the Controller that processes HTTP requests. They are not responsible for presentation tasks. That can be either servlets or JSP. They take the task of managing the application state, security, and presentation uniformity and thus, have a single point of entry. This explains the approach and the process of execution of a request.

The following steps execute a JSP request from the time the request is received from client until it is processed and sent back to client. Step1: Request from Client: A JSP page has the extension as .jsp. The client request is made on the web browser by going to the .jsp extension JSP file. Step2: Request Sent To Server: The request received from client (web browser) is sent to the server side. Step3: JSP Servlet Engine: Since the extension of request made has .jsp extension, it indicates that it is a JSP file and therefore the web server passes the request received to the JSP Servlet Engine. Step4: Process of generating servlet: JSP files are compiled by the JSP engine into a servlet. This step creates the .jsp file as a Java servlet source file. Step5: Process of making class file: The source file from Step4 is compiled into a class file. Step6: Instantiation of Servlet: The instantiation of servlet is performed using the init and service methods. In these methods, the jspInit() method is defined by the developer and the jspService method is generated by the JSP engine. Step7: Output HTML: The request received from client is executed and the output is sent as HTML. Step8: Client Receives the Output: The Client Receives the Output and thus the result namely the HTML gets displays in the client browser.

JDBC concepts and terminology JDBC is a Java API and a standard part of the Java class libraries that control basic functions for Java application development. The SQL capabilities that JDBC provides are similar to those of ODBC and dynamic SQL. The following sequence of events is typical of a JDBC application: 1. 2. 3. Create a Connection object call the getConnection( ) static method of the DriverManager class to create a Connection object. This establishes a database connection. Generate a Statement object use the Connection object to generate a Statement object. Pass a SQL statement to the Statement object if the statement is a query, this action returns a ResultSet object. The ResultSet object contains the data returned from the SQL statement, but provides it one row at a time (similar to the way a cursor works). 4.
o o

Loop over the rows of the results set call the next( ) method of the ResultSet object to: Advance the current row (the row in the result set that is being exposed through the ResultSet object) by one row. Return a Boolean value (true/false) to indicate whether there is a row to advance to.

5.

For each row, retrieve the values for columns in the ResultSet object use the getInt( ), getString( ), or similar method to identify either the name or position of the column.

JDBC Architecture: The JDBC API supports both two-tier and three-tier processing models for database access but in general JDBC Architecture consists of two layers: 1. JDBC API: This provides the application-to-JDBC Manager connection. 2. JDBC Driver API: This supports the JDBC Manager-to-Driver Connection.

The JDBC API uses a driver manager and database-specific drivers to provide transparent connectivity to heterogeneous databases. The JDBC driver manager ensures that the correct driver is used to access each data source. The driver manager is capable of supporting multiple concurrent drivers connected to multiple heterogeneous databases. Following is the architectural diagram, which shows the location of the driver manager with respect to the JDBC drivers and the Java application: Common JDBC Components: The JDBC API provides the following interfaces and classes: DriverManager: This interface manages a list of database drivers. Matches connection requests from the java application with the proper database driver using communication subprotocol. The first driver that recognizes a certain subprotocol under JDBC will be used to establish a database Connection. Driver: This interface handles the communications with the database server. You will interact directly with Driver objects very rarely. Instead, you use DriverManager objects, which manages objects of this type. It also abstracts the details associated with working with Driver objects Connection : Interface with all methods for contacting a database. The connection object represents communication context, i.e., all communication with database is through connection object only. Statement : You use objects created from this interface to submit the SQL statements to the database. Some derived interfaces accept parameters in addition to executing stored procedures. ResultSet: These objects hold data retrieved from a database after you execute an SQL query using Statement objects. It acts as an iterator to allow you to move through its data. SQLException: This class handles any errors that occur in a database application.

What is JDBC Driver ? JDBC drivers implement the defined interfaces in the JDBC API for interacting with your database server. For example, using JDBC drivers enable you to open database connections and to interact with it by sending SQL or database commands then receiving results with Java. The Java.sql package that ships with JDK contains various classes with their behaviours defined and their actual implementaions are done in third-party drivers. Third party vendors implements the java.sql.Driver interface in their database driver. JDBC Drivers Types: JDBC driver implementations vary because of the wide variety of operating systems and hardware platforms in which Java operates. Sun has divided the implementation types into four categories, Types 1, 2, 3, and 4, which is explained below: Type 1: JDBC-ODBC Bridge Driver: Type 2: JDBC-Native API: Type 3: JDBC-Net pure Java: Type 4: 100% pure Java: JDBC Basics - Java Database Connectivity Steps Before you can create a java jdbc connection to the database, you must first import the java.sql package. import java.sql.*; The star ( * ) indicates that all of the classes in the package java.sql are to be imported. 1. Loading a database driver,

In this step of the jdbc connection process, we load the driver class by calling Class.forName() with the Driver class name as an argument. Once loaded, the Driver class creates an instance of itself. A client can connect to Database Server through JDBC Driver. Since most of the Database servers support ODBC driver therefore JDBC-ODBC Bridge driver is commonly used. The return type of the Class.forName (String ClassName) method is Class. Class is a class in java.lang package. try { Class.forName(sun.jdbc.odbc.JdbcOdbcDriver); //Or any other driver } catch(Exception x){ System.out.println( Unable to load the driver class! ); } 3. Creating a oracle jdbc Connection The JDBC DriverManager class defines objects which can connect Java applications to a JDBC driver. DriverManager is considered the backbone of JDBC architecture. DriverManager class manages the JDBC drivers that are installed on the system. Its getConnection() method is used to establish a connection to a database. It uses a username, password, and a jdbc url to establish a connection to the database and returns a connection object. A jdbc Connection represents a session/connection with a specific database. Within the context of a Connection, SQL, PL/SQL statements are executed and results are returned. An application can have one or more connections with a single database, or it can have many connections with different databases. A Connection object provides metadata i.e. information about the database, tables, and fields. It also contains methods to deal with transactions. JDBC URL Syntax:: jdbc: <subprotocol>: <subname> JDBC URL Example:: jdbc: <subprotocol>: <subname>Each driver has its own subprotocol Each subprotocol has its own syntax for the source. Were using the jdbc odbc subprotocol, so the DriverManager knows to use the sun.jdbc.odbc.JdbcOdbcDriver. try{ Connection dbConnection=DriverManager.getConnection(url,loginName,Password) } catch( SQLException x ){ System.out.println( Couldnt get connection! ); } 3. Creating a jdbc Statement object, Once a connection is obtained we can interact with the database. Connection interface defines methods for interacting with the database via the established connection. To execute SQL statements, you need to instantiate a Statement object from your connection object by using the createStatement() method. Statement statement = dbConnection.createStatement(); A statement object is used to send and execute SQL statements to a database. Three kinds of Statements Statement: Execute simple sql queries without parameters. Statement createStatement() Creates an SQL Statement object. Prepared Statement: Execute precompiled sql queries with or without parameters. PreparedStatement prepareStatement(String sql) returns a new PreparedStatement object. PreparedStatement objects are precompiled SQL statements. Callable Statement: Execute a call to a database stored procedure. CallableStatement prepareCall(String sql)

returns a new CallableStatement object. CallableStatement objects are SQL stored procedure call statements. 4. Executing a SQL statement with the Statement object, and returning a jdbc resultSet. Statement interface defines methods that are used to interact with database via the execution of SQL statements. The Statement class has three methods for executing statements: executeQuery(), executeUpdate(), and execute(). For a SELECT statement, the method to use is executeQuery . For statements that create or modify tables, the method to use is executeUpdate. Note: Statements that create a table, alter a table, or drop a table are all examples of DDL statements and are executed with the method executeUpdate. execute() executes an SQL statement that is written as String object. ResultSet provides access to a table of data generated by executing a Statement. The table rows are retrieved in sequence. A ResultSet maintains a cursor pointing to its current row of data. The next() method is used to successively step through the rows of the tabular results. ResultSetMetaData Interface holds information on the types and properties of the columns in a ResultSet. It is constructed from the Connection object. Test JDBC Driver Installation import javax.swing.JOptionPane; public class TestJDBCDriverInstallation_Oracle { public static void main(String[] args) { StringBuffer output = new StringBuffer(); output.append(Testing oracle driver installation \n); try { String className = sun.jdbc.odbc.JdbcOdbcDriver; Class driverObject = Class.forName(className); output.append(Driver : +driverObject+\n); output.append(Driver Installation Successful); JOptionPane.showMessageDialog(null, output); } catch (Exception e) { output = new StringBuffer(); output.append(Driver Installation FAILED\n); JOptionPane.showMessageDialog(null, output); System.out.println(Failed: Driver Error: + e.getMessage()); } } } Download JDBC Sample Code Java JDBC Connection Example, JDBC Driver Example import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.SQLException; public class JDBCDriverInformation { static String userid=scott, password = tiger; static String url = jdbc:odbc:bob; static Connection con = null; public static void main(String[] args) throws Exception { Connection con = getOracleJDBCConnection(); if(con!= null){

System.out.println(Got Connection.); DatabaseMetaData meta = con.getMetaData(); System.out.println(Driver Name : +meta.getDriverName()); System.out.println(Driver Version : +meta.getDriverVersion()); }else{ System.out.println(Could not Get Connection); } } public static Connection getOracleJDBCConnection(){ try { Class.forName(sun.jdbc.odbc.JdbcOdbcDriver); } catch(java.lang.ClassNotFoundException e) { System.err.print(ClassNotFoundException: ); System.err.println(e.getMessage()); } try { con = DriverManager.getConnection(url, userid, password); } catch(SQLException ex) { System.err.println(SQLException: + ex.getMessage()); } return con; } }

Navigating a Result Set: There are several methods in the ResultSet interface that involve moving the cursor, including: S.N. 1 2 3 4 5 6 Methods & Description public void beforeFirst() throws SQLException Moves the cursor to just before the first row public void afterLast() throws SQLException Moves the cursor to just after the last row public boolean first() throws SQLException Moves the cursor to the first row public void last() throws SQLException Moves the cursor to the last row. public boolean absolute(int row) throws SQLException Moves the cursor to the specified row public boolean relative(int row) throws SQLException Moves the cursor the given number of rows forward or backwards from where it currently is pointing.

public boolean previous() throws SQLException Moves the cursor to the previous row. This method returns false if the previous row is off the result set public boolean next() throws SQLException Moves the cursor to the next row. This method returns false if there are no more rows in the result set public int getRow() throws SQLException Returns the row number that the cursor is pointing to. public void moveToInsertRow() throws SQLException Moves the cursor to a special row in the result set that can be used to insert a new row into the database. The current cursor location is remembered. public void moveToCurrentRow() throws SQLException Moves the cursor back to the current row if the cursor is currently at the insert row; otherwise, this method does nothing

9 10

11

Viewing a Result Set: The ResultSet interface contains dozens of methods for getting the data of the current row. There is a get method for each of the possible data types, and each get method has two versions: 1. One that takes in a column name. 2. One that takes in a column index. For example, if the column you are interested in viewing contains an int, you need to use one of the getInt() methods of ResultSet: S.N. 1 2 Methods & Description public int getInt(String columnName) throws SQLException Returns the int in the current row in the column named columnName public int getInt(int columnIndex) throws SQLException Returns the int in the current row in the specified column index. The column index starts at 1, meaning the first column of a row is 1, the second column of a row is 2, and so on.

Similarly there are get methods in the ResultSet interface for each of the eight Java primitive types, as well as common types such as java.lang.String, java.lang.Object, and java.net.URL There are also methods for getting SQL data types java.sql.Date, java.sql.Time, java.sql.TimeStamp, java.sql.Clob, and java.sql.Blob. Check the documentation for more information about using these SQL data types. For a better understanding, I would suggest to study Viewing - Example Code. Updating a Result Set: The ResultSet interface contains a collection of update methods for updating the data of a result set. As with the get methods, there are two update methods for each data type: 1. One that takes in a column name. 2. One that takes in a column index. For example, to update a String column of the current row of a result set, you would use one of the following updateString() methods: S.N. 1 2 Methods & Description public void updateString(int columnIndex, String s) throws SQLException Changes the String in the specified column to the value of s. public void updateString(String columnName, String s) throws SQLException

Similar to the previous method, except that the column is specified by its name instead of its index. There are update methods for the eight primitive data types, as well as String, Object, URL, and the SQL data types in the java.sql package. Updating a row in the result set changes the columns of the current row in the ResultSet object, but not in the underlying database. To update your changes to the row in the database, you need to invoke one of the following methods. S.N. 1 2 3 4 5 Methods & Description public void updateRow() Updates the current row by updating the corresponding row in the database. public void deleteRow() Deletes the current row from the database public void refreshRow() Refreshes the data in the result set to reflect any recent changes in the database. public void cancelRowUpdates() Cancels any updates made on the current row. public void insertRow() Inserts a row into the database. This method can only be invoked when the cursor is pointing to the insert row.

JavaBean:
A JavaBean is a specialized Java class. In this short JavaBeans tutorial, Ill show you the rules with which a JavaBean must comply and then Ill give you examples of creating a JavaBean, first in straight Java and then in JSP. JavaBean Rules

A JavaBean must have a public, no-argument constructor (a default constructor). This is required so that Java frameworks can facilitate automated instantiation. The JavaBean class attributes must be accessed via accessor and mutator methods that follow a standard naming convention (getXxxx and setXxxx, isXxxx for boolean attributes). Its important to note that an attribute is a named memory location that contains a value, while a property refers to this set of methods used to access an attribute. This allows frameworks to automate operations on attribute values. The JavaBean class should be serializable. This allows Java applications and frameworks to save, store, and restore the JavaBeans state.

JavaBean Example 1 // The class is serialized for IO operations 2 public class Person implements java.io.Serializable { 3 // attributes declared as private 4 private String name; 5 private boolean deceased; 6

7 8 9 1 0 1 1 1 2 1 3 1 // Default Constructor 4 public Person() { } 1 5 // getXxxx to access the name attribute 1 public String getName() { 6 return this.name; 1 } 7 1 // setXxxx to mutate the name attribute 8 public void setName(String name) { 1 this.name = name; 9 } 2 0 // isXxxx to access boolean attribute 2 public boolean isDeceased() { 1 return this.deceased; 2 } 2 2 // setXxxx to mutate boolean attribute 3 public void setDeceased(boolean deceased) { 2 this.deceased = deceased; 4 } 2 } 5 2 6 2 7 2 8 2 9 3 0 Definition: What is a Bean? If you use builder tools, such as Delphi or Visual Basic, you are already familiar with the notion of a bean. A JavaBean is a reusable software component that is written in Java programming language. It can be visually manipulated in builder tools. A JavaBean is often referred to simply as a Bean. Software components are self-contained, reusable software units. Using visual application builder tools, software components can be composed into applets, applications, servlets, and composite

components. You perform this composition within a graphical user interface, and you can immediately see the results of your work. Reusable Software Components Reusable software components apply the concept of interchangeable parts to the field of software construction. Other industries have long profited from reusable components. For example, the builder tool above shows a calculator component that is built from 16 button components, a text field component, and a panel with buttons and a text display. Reusable software components can be simple, such as buttons, text fields, list boxes, scrollbars, and dialogs. If you use visual component assembly tools, such as Visual Age, Delphi, Visual Basic, Mojo, or even PowerBuilder, you are familiar with the notion of software components. Visual Basic Extensions (VBXs) were the first widely used software components, followed by language-independent OLE Custom Controls (OCXs). UNIX programmers will be more familiar with widgets and toolkits. Reusable components add standardized interfaces and object introspection mechanisms to widgets, allowing builder tools to query components about their properties and behavior. Keep in mind, too, that software components need not be visible in a running application; they only need to be visible when the application is constructed. For example, the builder tool above shows a calculator component that is built from 16 button components, a text field component, and a panel with buttons and a text display are placed. Because you are looking at the component in a builder tool, you can see five additional components (NewCalcFlag, zeroInteger, Accumulator, EnteredString, and opcharHolder) which are normally invisible when an application displays the calculator. These additional components hold values or strings used by the calculator for intermediate calculations, operation codes, and display strings. A programmer can move, query, or visually hook together components while operating a builder tool. Often, such components do their work while the application is running, though they are invisible to the user. You can purchase custom JavaBean components from third party vendors. You can also purchase builder tools or application construction programs that support JavaBeans. Application construction tools let you build Java applications using the mouse as your primary input mechanism. You select components (from pallets, panels, or menus) and drop them into a form, or client window. You can change the behavior and look of these components by editing their properties, and you can link the actions of one component to another via events and event handlers. Components can be nested and arbitrarily complex. For example, a calculator built from components becomes, itself, a component to another application. Custom-built components are easily added to builder tool palettes. More complex components include barcharts, graphical diagram editors, and word processors. Basic Bean Concepts JavaBeans, regardless of their functionality, are defined by the following features.

Introspection Beans support introspection, which allows a builder tool to analyze how Beans work. They adhere to specific rules called design patterns for naming Bean features. Each Bean has a related Bean information class, which provides property, method, and event information about the Bean itself. Each Bean information class implements a BeanInfo interface, which explicitly lists the Bean features that are to be exposed to application builder tools. Properties Properties control a Bean's appearance and behavior. Builder tools introspect on a Bean to discover its properties and to expose them for manipulation. As a result, you can change a Bean's property at design time.

Customization The exposed properties of a Bean can be customized at design time. Customization allows a user to alter the appearance and behavior of a Bean. Beans support customization by using property editors or by using special, sophisticated Bean customizers. Events Beans use events to communicate with other Beans. Beans may fire events, which means the Bean sends an event to another Bean. When a Bean fires an event it is considered a source Bean. A Bean may receive an event, in which case it is considered a listener Bean. A listener Bean registers its interest in the event with the source Bean. Builder tools use introspection to determine those events that a Bean sends and those events that it receives. Persistence Beans use Java object serialization, implementing the java.io.Serializable interface, to save and restore state that may have changed as a result of customization. State is saved, for example, when you customize a Bean in an application builder, so that the changed properties can be restored at a later time. Methods All JavaBean methods are identical to methods of other Java classes. Bean methods can be called by other Beans or via scripting languages. A JavaBean public method is exported by default.

While Beans are intended to be used primarily with builder tools, they need not be. Beans can be manually manipulated by text tools through programmatic interfaces. All key APIs, including support for events, properties, and persistence, are designed to be easily read and understood by programmers, as well as by builder tools. For your first JavaBean, let's look at the BDK BeanBox. Although in this tutorial we use the BeanBox to create a JavaBean, the BeanBox is generally used to test your JavaBeans. The BeanBox is considered a reference builder tool environment. It is not designed for building GUI applications, nor is it meant to have a look and feel of such other builder tools as Visual Age, Delphi, or Visual Basic. You can create a JavaBean and then use the BeanBox to test that it runs properly. If a JavaBean runs properly in the BeanBox, you can be sure that it works properly with other commercial builder tools. Starting the BeanBox When you start the BeanBox, you'll see three windows:

ToolBox window BeanBox window Properties window

The ToolBox window displays the JavaBeans that are currently installed in the BeanBox, such as the Beans the come with the BeanBox demo. When the BeanBox starts, it automatically loads its ToolBox with the Beans in the JAR files contained in the bean/jars directory. You can add additional Beans, such as your own Beans, to the ToolBox. The next lesson, Writing a Simple JavaBean, explains how to add Beans to the ToolBox. The BeanBox window itself appears initially as an empty window. You use this empty window, sometimes referred to as a "form" by other builder tools, for building applications. The third window, the Properties window, displays the current properties for the selected Bean. If no Bean is selected, such as when you first start the BeanBox or if you click in the BeanBox window's background, then the Properties window displays the BeanBox properties. You can use the Properties window or sheet to edit a Bean's properties. Using the BDK BeanBox Using the Demo BDK JavaBeans

The easiest way to understand how the BeanBox works is to use it. The BeanBox enables you to construct simple Beans applications without writing any Java code. As a first example, you can build a simple "Juggling Duke" application in which Duke will start or stop juggling depending on which of two buttons you push. In this lesson, you'll learn how to:

Drop Beans from the ToolBox into the BeanBox and change their properties using the Properties sheet and associated property editors. Have one Bean fire an event and another Bean react to the fired event.

Back to Top Creating your Bean We'll start by dropping the Juggler Bean from the ToolBox into an empty BeanBox. 1. Click on Juggler Bean to select from the list of Beans in the Toolbox window.

Notice that the cursor changes to a crosshair. 2. Place the cursor anywhere in the BeanBox, then click the mouse. This inserts a Juggler Bean into the BeanBox window. The highlighted box surrounding the Juggler indicates the Juggler is the currently selected bean.

Next we'll look at adding a start button to control the Juggler. This button Bean is an instance of the OurButton Bean class.

3.

Click the OurButton Bean name in the ToolBox, then place an instance of the button in the BeanBox. Select the button in the BeanBox so that the button's properties display in the Property sheet. 4. Edit the label field in the button's Property sheet so that the button's label reads "start."

Notice that the text for the button in the BeanBox changes from "press" to "start" after you type "start" into the label field of the property sheet editor. 5. Use the BeanBox Edit menu to select an action event to be fired by the start button. Before choosing the event action, be sure that you have selected the start button. 1. Notice that once you select the actionPerformed menu item, BeanBox enters a state where a line emanates from the start button and follows the mouse as you move it around the window. This indicates that the button is the selected source for the action event, and that your next mouse press should be over the target Bean which defines appropriate event-handler methods, in this case the Juggler Bean.

2.

Drag the line from the start button and release it over the Juggler Bean. A dialog appears listing applicable event handlers defined by the Juggler Bean. 3. Select the startJuggling method as the target for the event, then press OK. Now, when you press the start button Duke should start tossing beans around in a circle over his head like a professional juggler. You can control Duke's juggling speed by manually setting the property value labeled animationRate in the Juggler's property sheet editor. For the appropriate property sheet editor to appear, the Juggler must be the currently selected Bean within the BeanBox frame.

Completing your Program To complete the example program, add a stop button. Repeat the steps you took when you added the start button and connected it to the appropriate Juggler action. 1. Select OurButton from the list of available Beans in the Toolbox menu, then drop it below the start button in the BeanBox.

When the new button is the currently selected Bean, the appropriate property editor appears. 2. 3. 4. 5. 6. Edit the label field of the property sheet to read "stop." Hook up the action event from the stop button to the Juggler's stopJuggling event-handler method. Make sure the stop button is the currently selected bean. Select the actionPerformed event from the Edit/Events menu. Drag the event line from the stop button source to the Juggler Bean target. Press and release the mouse button with the connection line over the Juggler. The dialog of applicable event-handler methods defined for the Juggler Bean displays; select the stopJuggling event and click OK.

You should now be able to start and stop the juggler by pressing the appropriate button. Note : You've learned how to select Beans from the ToolBox and place them in the BeanBox. Once in the BeanBox, you can use the Bean's Property sheet and property editors to change its appearance. You can also use the BeanBox menu options to connect events from one Bean to another, to initiate and control Bean actions. Keep in mind that the BeanBox is not an application builder tool. Its main purpose is to test Beans and verify that introspection and event hookup works properly. You would not really use the BeanBox to build and run an application. Instead, think of the BeanBox as a reference builder tool. If your bean runs properly in the BeanBox, and it reports the proper events that you want your bean to fire as well as the proper event handlers for events you want it to respond to, you can be confident that your bean will work properly in other Beans-enabled builder tools. EJB Roles The two fundamental roles in the RMI environment: the client of the remote object, and the object itself, which acts as a kind of server or service provider. These two roles exist in the EJB environment as well, but EJB adds a third role, called the container provider. The container provider is responsible for implementing all the extra services for an EJB object that I mentioned earlier: transaction processing, security, object persistence, and resource pooling. If you're familiar with CORBA, you can think of the

EJB container as being roughly equivalent to the ORB in CORBA, with a few of the CORBA services thrown in as well. In EJB, however, the container is strictly a server-side entity. The client doesn't need its own container to use EJB objects, but an EJB object needs to have a container in order to be exported for remote use. Figure 7-1 shows a conceptual diagram of how the three EJB roles interact with each other.

Figure 7-1. The basic roles in an EJB environment Service & Tool Provider : provides Server, Container and integrates with distributed facilities

EJB Provider creates EJB components

Application Assembler assembles apps from per-built EJB comp

Deployment Specialist deploys apps and understands architecture issues

The EJB Client An EJB client uses remote EJB objects to access data, perform tasks, and generally get things done. In the EJB environment, the first action a client performs is to find the home interface for a type of EJB object that it wants to use. This home interface is a kind of object factory, used to create new instances of the EJB type, look up existing instances (only when using entity EJB objects, discussed later), and delete EJB

objects. This is a bit different from RMI, where the client first has to get a direct handle to an existing RMI object. In many RMI applications, however, this first RMI object is a kind of object factory that creates other RMI object references. So, in a sense, the use of home interfaces in EJB is just formalizing the role of factory objects in distributed component applications. EJB home interfaces are located by clients using JNDI (see Chapter 6, "JNDI", for more information). An EJB server publishes the home interface for a particular EJB object under a particular name in a JNDI namespace. The EJB client needs to specify the JNDI server and the name that the EJB home interface is stored under in order to start things off. The following code shows a simple EJB client that uses remote Person beans: import javax.ejb.*; import javax.naming.*; import java.rmi.*; import java.util.Properties; public class PersonClient { public static void main(String[] args) { String name = args[0]; try { // Get a JNDI context for our EJB server (EJBHome, in this case) Properties p = new Properties(); p.put(Context.INITIAL_CONTEXT_FACTORY, "com.ejbhome.naming.spi.rmi.RMIInitCtxFactory"); // Add URL, host or port options, if needed...; Context context = new InitialContext(p); // Get the home interface for Person beans PersonHome pHome = (PersonHome)context.lookup("People"); // Create a named person Person person = pHome.create(name); // Use the remote stub interface to access the person's data ... } catch (NoSuchPersonException nspe) { System.out.println("Invalid person: " + name); } catch (Exception e) { System.out.println("Error while creating/using person."); } } }

We'll examine the details of this client a bit later in the chapter, but the example shows the fundamental steps an EJB client performs:

Get a JNDI context from the EJB server. Use this context to look up a home interface for the bean you want to use. Use this home interface to create (or find) a bean. Call methods on the bean.

EJB clients utilizes the Java Naming and Directory Interface (JNDI) to look up for the references to home interfaces use home and remote EJB interfaces to utilize all EJB-based functionality The Enterprise JavaBeans Object If you develop your own EJB object, you need to provide three Java interfaces/classes in order to fully describe your EJB object to an EJB container:

A home interface A remote interface An enterprise bean implementation

The remote interface and the object implementation are similar to the corresponding RMI interfaces. A client issues method requests through a stub derived from the remote interface and eventually these requests make their way to the corresponding bean instance on the server. The home interface is a new twist: it acts as a bean factory, providing a way for a client to create, locate, and destroy EJB objects that it uses. With the home interface in the picture, the remote interface acts as the interface the client uses to interact with EJB objects, and the implementation is where the object itself does its thing. Here is an example home interface for the Person bean used in the previous example: import javax.ejb.*; import java.rmi.RemoteException; import java.util.Hashtable; public interface PersonHome extends EJBHome { // Create a new (nameless) person public Person create() throws RemoteException; // Create a named person. // Throws an exception if the person can't be found. public Person create(String name) throws RemoteException, NoSuchPersonException; // Lookup a Person by name (the "primary key") public Person findByPrimaryKey(PersonPK key) throws RemoteException, FinderException;

// Lookup people with a given string in their name. public Enumeration findByPartialName(String fragment) throws RemoteException, FinderException; } This home interface includes methods to create Person beans and to find them if they already exist on the server. The remote interface for our Person bean is shown here: import javax.ejb.*; import java.rmi.Remote; import java.rmi.RemoteException; public interface Person extends Remote, EJBObject { public String getName() throws RemoteException; public void setName(String name) throws RemoteException; } This interface shows the business methods that are available to clients. When a client gets a reference to a bean through the PersonHome interface, it is given a stub that implements the Person interface. The EJB object implementation needs to implement all the business methods in the remote interface, plus some methods used by the container to tell it about various events in its lifetime. The EJB object does not need to implement the remote interface, which is another new twist compared to RMI, where the server object always implements the remote interface. In EJB, the container arranges for method calls on the remote interface to be transferred to the EJB object. You just need to ensure that the EJB object has methods that match the signatures of the methods in the remote interface. We'll see an example of EJB object implementation a bit later. Various pieces of these Java classes (home, remote, and implementation) are provided for the sake of the client, to allow a client to create EJB objects and call remote methods on them. Other pieces are provided for the EJB container, to allow it to notify the EJB object about transaction- and persistence-related events, for example. In addition to the interfaces that describe the EJB object type, an EJB object also provides deployment descriptors to its containers. The deployment descriptors tell the container the name to use for registering the bean's home interface in JNDI, how to manage transactions for the bean, the access rights that remote identities are given to invoke methods on the EJB, and how persistence of the EJB objects should be handled. The container does all the heavy lifting with regard to providing these services, but the EJB object has to tell the container how it would prefer to have these services managed. There are two fundamental types of Enterprise JavaBeans: session beans and entity beans.[2] A session bean is accessed by a single client at a time and is nonpersistent. It lives for a specific period of time (a session), and then gets removed by the server. An entity bean, on the other hand, represents a data entity stored in persistent storage (e.g., a database or filesystem). It can be accessed by multiple clients concurrently and is persistent beyond a client session or the lifetime of the EJB server. [2]In Version 1.0 of the EJB specification, support for entity beans is optional in compliant EJB servers. To illustrate the difference between session and entity beans, suppose you're building an online banking system using EJB components. An automated bank teller, which reports on account balances and executes deposits and withdrawals on specified accounts, could be implemented as a session bean. A single client

uses the teller bean to perform services on bank accounts that are maintained in some separate persistent store (the bank's database). A EJB object that directly represents a bank account, however, should be an entity bean. Multiple clients can access the account to perform transactions, and the state of the account entity should be persistent across the lifetime of the online banking server. The EJB Container Most readers need to be familiar only with EJB containers from the perspective of an EJB client or an EJB object. For example, a Java application server that you might use to deploy an EJB-based application provides an implementation of the EJB container role. EJB-enabled application servers, with their own EJB containers and deployment tools, are available from Weblogic/BEA, Bluestone, IBM, Netscape, and Art Technology Group, among others. The EJB container represents the value-added features of EJB over standard remote objects built using RMI or CORBA. The EJB container manages the details of transactional processing, resource pooling, and data persistence for you, which reduces the burden on client applications and EJB objects and allows them to deal with just the business at hand. An EJB application server can contain multiple EJB containers, each managing multiple EJB objects. In this chapter, I'll refer to EJB servers and EJB containers somewhat interchangeably, depending on the context. In general, though, the container is strictly the runtime elements that interact directly with your EJB objects to provide client proxy services and notifications, while the server is the other glue outside the core EJB standard that integrates the EJB containers into a larger application management structure of some kind. An EJB container is the heart of an EJB environment, in the same way an ORB is the heart of a CORBA environment. The container registers EJB objects for remote access, manages transactions between clients and EJB objects, provides access control over specific methods on the EJB, and manages the creation, pooling, and destruction of enterprise beans. The container also registers the home interface for each type of bean under a given name in a JNDI namespace, allowing remote clients to find the home interfaces and use them to create enterprise beans. Once you provide the EJB container with the home and remote interfaces and the implementation class for your bean, along with a deployment descriptor, the container is responsible for generating the various classes that connect these components, as shown in Figure 7-2. The home and remote interfaces you provide are RMI Remote interfaces; the container generates both the client stubs and the server-side implementation for these interfaces. When a client looks up a bean's home interface through JNDI, it receives an instance of the home stub class. All methods invoked on this stub are remotely invoked, via RMI, on the corresponding home implementation object on the EJB server. Similarly, if the client creates or finds any beans through the home stub, the client receives remote object stubs, and methods invoked on the stubs are passed through RMI to corresponding implementation objects on the server. These remote objects are linked, through the EJB container, to a corresponding enterprise bean object, which is an instance of your bean-implementation class. Optionally, the EJB container may also generate a container-specific subclass of your bean implementation (e.g., if it wants to augment some of your bean methods to facilitate synchronization with the container).

Figure 7-2. Relationship of bean-provider classes and container-generated classes The container receives client requests to create, look up, and/or remove beans. It either handles them itself or passes the requests to corresponding methods on the EJB object. Once the client obtains a reference to a remote interface for an EJB object, the container intercedes in remote method calls on the bean, to provide the bean with required transaction management and security measures. The container also provides support for persistence of enterprise beans, either by storing/loading the bean state itself or by notifying the bean that it needs to store or reload its state from persistent storage. A container can maintain multiple EJB objects and object types during its lifetime. The container has some freedom to manage resources on the server for performance or other reasons. For example, a container can choose to temporarily serialize a bean and store it to the server filesystem or some other persistent store; this is called passivating a bean. The EJB object is notified of this and given a chance to release any shared resources or transient data that shouldn't be serialized. The bean is also notified after it is activated again, to allow it to restore any transient state or reopen shared resources. An EJB container can make any EJB object type available for remote use. When you deploy an EJB object within an EJB server, you can specify how the container should manage the bean during runtime, in terms of transaction management, resource pooling, access control, and data persistence. This is done using deployment descriptors, which contain parameter settings for these various options. These settings can be customized for each deployment of an EJB object. You might purchase an EJB object from a vendor and deploy it on your EJB server with a particular set of container management options, while someone else who purchased the same bean can deploy it with a different set of deployment options. We discuss the details of the runtime options available in deployment descriptors and how to use them later in this chapter, when we talk about deploying EJB components.

Roles in EJB

EJB specification gives a clear description of each of these roles and their associated responsibilities.

a) Enterprise Bean Provider


It is the person or group that writes and packages EJBs. It might be a third-party vendor of EJB components, or it might be an information systems programmer who writes EJBs to implement their companys business logic. Because the container must provide transaction and network communication support, the enterprise bean provider does not need to be an expert at low-level system programming, networking or transaction processing. The end product is an ejb-jar file, which contains the Enterprise bean, its supporting classes, and information that describes how to deploy the bean.

b) Deployer

The deployer takes an ejb-jar file and installs it into an EJB container. The deployers task begins with the receipt of an ejb-jar file, and ends with the installation of the ejb-jar file in the container. This task is typically handled by the System Administrator in MIS world.

c) Application Assembler

An application assembler builds applications using EJBs classes. An MIS programmer may purchase a prepackaged set of EJBs that implement an accounting system. Then the programmer might use tools to customize the beans. The application assembler might also need to provide a user-interface client program. This role is roughly analogous to that of a Systems Integrator in the MIS world.

d) EJB Server Provider


An EJB Server Provider provides a server that can contain EJB containers. The EJB 1.0 specification does not describe the interface between the server and the container, so the EJB server provider and the EJB container provider will likely be one and the same for any given product. The diagram shows the relationships among the EJB server, the EJB container, and the EJB bean. An EJB server provides services to an EJB container and an EJB container provides services to an Enterprise Java Bean. The role of the EJB server provider is similar to that of a database system vendor.

e) EJB Container Provider


An EJB container is the world in which an EJB bean lives. The container services requests from the EJB, forwards requests from the client to the EJB, and interacts with the EJB server. The container provider must provide transaction support, security and persistence to beans. It is also responsible for running the beans and for ensuring that the beans are protected from the outside world.

f) System Administrator

System Administrators are responsible for the day-to-day operation of the EJB server. Their responsibilities include keeping security information up-to-date and monitoring the performance of the server.

EJB Container or EJB Server An EJB container is nothing but the program that runs on the server and implements the EJB specifications. EJB container provides special type of the environment suitable for running the enterprise components. Enterprise beans are used in distributed applications that typically contains the business logic. The container performs the various tasks few of them are illustrated below: Transaction Management: EJB container allows you for transaction management that enables the transaction services, a low level implementation of transaction management and coordination. Container uses the Java Transaction APIs to expose the transaction services. JTA, a high level interface is used to control transactions.

Security: JSE mainly focuses on how to become the environment more secure. Enterprise beans add this feature to provide transparent security so that access to the beans can be made secure just by applying the security attributes rather than coding against the security API. Resource and Life Cycle Management: EJB container manages the resources like database connections, threads and socket on behalf of enterprise beans. Container creates, destroys, registers the objects and also activates and passivates them. The container is also capable of reusing them whenever required. Remote Accessibility: A client on the remote machine containing JVM can invoke an enterprise bean running on the host machine. To support the remote accessibility the container uses the remote procedure call technology. When the software is developed by using the OOPs concept then Remote procedure call (RPC) may be referred to as Remote Method Invocation (RMI). Concurrency Control: Concurrency control is necessary to know the basics of collisions and type of collisions that can occur. If you are not interested to occur them then you can bypass them later they will cause to create problems. So try to detect and resolve them. To do so the EJB Container supports for various types of concurrency controls. First we will concentrate on collision and then techniques to resolve these collisions. Collision: A collision can occur when two or more transactions tries to change the entities within a system of records. There are three types through which two or more activities may interfere:

Dirty read Non Repeatable read Phantom read

Control mechanism: Mainly two mechanism are used to control the concurrency.

Optimistic Locking Pessimistic Locking

Clustering and load-balancing: Clustering is the process of combining the multiple peripherals, computers and other resources into a single unit. A clustered system then works as load balanced system. In a distributed system when a request is send to the server, an algorithm running on the server decides which server has less load and sends the request to that server. EJB container encapsulates these features to provide smooth and efficient service. 3. Enterprise Beans Enterprise beans are the Java EE server side components that run inside the ejb container and encapsulates the business logic of an enterprise application. Enterprise applications are the software applications developed intended to use at large scale. These applications involves large number of data accessing concurrently by many users. Enterprise beans are used to perform various types of task like interacting with the client, maintaining session for the clients retrieving and holding data from the database and communicating with the server. Benefits of enterprise beans: Enterprise beans are widely used for developing large and distributed applications. EJB container provides the system-level services (like transaction management and security

authorization) to the enterprise beans. These services simplifies the development process of large and distributed applications and the developer just have to concentrate on solving the problem occurred in it. The client developer can focus only on the representation style of the client as all the business logic of the application is contained in the enterprise beans. The client developer does not bother about the code that implements business logic or the logic to access the databases. This means that the clients are thinner. It benefits the client to be thin because the client runs on the small devices. Developing new applications from the existing beans is much easier because the enterprise beans are portable components. That means applications developed by using the enterprise components can run on any complaint J2EE server. When to use the enterprise beans: Some of the points are illustrated below that signifies the use of enterprise beans.

Applications developed by using the enterprise beans deal with a variety of clients, simply by writing few lines of code, so that the client can locate the enterprise beans. The client locating the enterprise bean may be various, numerous and thin. Enterprise beans support transaction to ensure the integrity of the database. Transaction is the mechanism of managing the concurrent access of shared objects. Managing the fast growing number of users requires distributed application components across multiple machines means that the application must be scalable.

Types of enterprise beans: EJB 3.0 defines two types of enterprise beans. These are: 1. Session bean: These types of beans directly interact with the client and contains business logic of the business application. 2. Message driven bean: It works like a listener or a consumer for a particular messaging service such as Java Message API or JPA for short. What is a Session bean: A session bean is the enterprise bean that directly interact with the user and contains the business logic of the enterprise application. A session bean represents a single client accessing the enterprise application deployed on the server by invoking its method. An application may contain multiple sessions depending upon the number of users accessing to the application. A session bean makes an interactive session only for a single client and shields that client from complexities just by executing the business task on server side. A session bean can neither be shared nor can persist (means its value can not be saved to the database) its value. A session bean can have only one client. As long as the client terminates, session bean associated with this client is also terminated and the data associated with this bean is also destroyed. The above figure shows how Session Bean interacts with the clients as well as Entity Beans Session beans are divided into two parts.

Stateless: These types of session beans do not use the class variables (instance variables). So they do not persist data across method invocation and therefore there is no need to passivates the bean's instance. Stateless session beans provides the better scalability as the server do not need to keep track the state of a stateless session bean across various method calls. Stateful: These types of beans use the instance variables that allows the data persistent across method invocation because the instance variables allow persistence of data across method

invocation. The client sets the data to these variables which he wants to persist. Stateful session beans has the extra overhead for the server to maintain the state than the stateless session bean.

The user interface calls methods of session beans if the user wants to use the functionality of the session bean. Session beans can call to other session beans and entity beans. When to use session beans: Generally session beans are used in the following circumstances:

When there is only one client is accessing the beans instance at a given time. When the bean is not persistent that means the bean is going to exist no longer. The bean is implementing the web services.

Stateful session beans are useful in the following circumstances:


What the bean wants to holds information about the client across method invocation. When the bean works as the mediator between the client and the other component of the application. When the bean have to manage the work flow of several other enterprise beans.

Stateless session beans are appropriate in the circumstances illustrated below:


If the bean does not contain the data for a specific client. If there is only one method invocation among all the clients to perform the generic task.

Life Cycle of a Stateless Session Bean: Since the Stateless session bean does not passivates across method calls therefore a stateless session bean includes only two stages. Whether it does not exist or ready for method invocation. A stateless session bean starts its life cycle when the client first obtains the reference of the session bean. For this, the container performs the dependency injection before invoking the annotated @PreConstruct method if any exists. After invoking the annotated @PreConstruct method the bean will be ready to invoke its method by the client.

The below figure demonstrates how the Stateless Session Beans are created and destroyed. The container calls the annotated @PreDestroy method while ending the life cycle of the session bean. After this, the bean is ready for garbage collection.

Life Cycle of a Stateful Session Bean: A Stateful session bean starts its life cycle when the client first gets the reference of a stateful session bean. Before invoking the annotated method @PostConstruct the container performs any dependency injection after this the bean is ready. The container may deactivate a bean while in ready state (Generally the container uses the least recently use algorithm to passivates a bean). In the passivate mechanism the bean moves from memory to secondary memory. The container invokes the annotated @PrePassivate method before passivating the bean. If a client invokes a business method on the passivated bean then the container invokes the annotated @PostActivate method to let come the bean in the ready state.

The above image shows the various states of the Stateful Session Beans While ending the life cycle of the bean, the client calls the annotated @Remove method after this the container calls the annotated @PreDestroy method which results in the bean to be ready for the garbage collection.

UNIT II
Java Message Services (JMS): JMS API is an enterprise tool developed by Sun Microsystems used to develop the enterprise applications. JMS API supports to a framework that allows the development of portable and message based applications. JMS communicates in synchronous or in asynchronous mode by using point-to-point and the publish-subscribe models respectively. JMS has become vendor specific and many vendors such as IBM, Oracle, Hewlett-Packard, BEA Systems and Macromedia are providing the JMS implementation. JMS API: JMS APIs play an important role as comparing the RMI-IIOP protocol. You need to aware with different interfaces, low level topology issues like structure, messaging format, networking protocol and server location.

1.

Locate the JMS provider's ConnectionFactory instance: First establish the connection by using a ConnectionFactory instance to get access the JMS provider of the MOM product you are using. An administrator typically creates and configures the ConnectionFactory for the JMS client's use.

2. Create a JMS connection: A JMS connection manages the low level network communications similar to JDBC connection. Use ConnectionFactory to get a connection. For large deployment this connection may be load balance across a group of machines. 3. Create a JMS session: A JMS session object is used to send and receive the messages and works as the ConnectionFactory for message producers and message consumers. It also allows the encapsulation of messages in transactions. We use Connection to get the session object. 4. Locate the JMS Destination: A JMS destination is an object to which we are sending or from which we are receiving the messages. Locating the right destination is similar to tuning the channel in the right direction to get the clear picture while watching the television or answering the correct phone to get the desired message. 5. Create a JMS producer or a JMS consumer: If you are interested to send a message then you need an object to pass your message. This object is known as the JMS producer. If you want to receive a message you need to call a JMS object. This object is known as the Consumer object. To get hold an object Session and Destination are used. 6. Send or Receive a message: There may be different types of messages like text, streams, maps, bytes, objects and so on. To send a messages first instantiate it and then send it by using the Producer object. If you are intended to receive a message then first receive the message with the help of Consumer object and then crack it to see what it contains. All the points described above are applicable to both point-to-point as well as publish/subscribe. Here we are going to discuss JMS by taking the queuing system. Queuing system includes the following parts:

JMS Server: The JMS server maintains the message queue to receive emails. JMS Queue: In case of point-to-point messaging system, a queue is used to hold the messages from clients. Messages holding this queue are of MapMessages type that stores the information about the email as name/value pair. Email Message Client: A client of this messaging system creates the JMS message to put it on the JMS Queue. This message contains the information about the message to be sent out. Emil Message Driven Bean: It is the message driven bean that is responsible to take the JMS MapMessage to male it out.

JMS Architecture: Talk first about JMS while talking about the message driven beans. There are a lot of messaging systems exist in the market. Messaging systems provide a mechanism to exchange data and events asynchronously. JMS API defines a standard way to access any messaging system such as JDBC that enables the user to talk to SQL Server, Oracle and Sybase simply by using the same API. The additional benefits of JMS API are loose coupling between the generated request and the code that services the request. Here are some of the basics of the messaging server that one should know to more clearly understand the concept of JMS APIs:

Messaging Domains JMS Messages

Messaging Domains: A messaging system includes several models of operation. JMS API provides separate domains corresponding to different models. JMS provider is free to implement one or more domains. Point-to-Point and Publish/Subscribe are the two most commonly used domains. These two domains concludes the following concepts.

Producer: The client, responsible for sending the message to the destination is known as the producer. Consumer: The client, responsible for receiving the message is known as the consumer. Destination: Destination is the object used by the client to specify the target that uses it to send the message to or to receive the message from.

Point-to-Point (PTP): An application that uses the point-to-point technique for messaging has the following characteristics.

A PTP producer is the sender. A PTP consumer is the receiver. PTP uses a queue as the destination. A receiver can consume only a single message.

A call center application is the example of a PTP domain, where a phone call enters in the queue therefore only one operator takes care of this call rather than all of the operators. Publish/Subscribe (pub/sub): An application that uses the pub/sub technique must include the following characteristics.

A pub/sub producer is the publisher A pub/sub consumer is the subscriber pub/sub uses the topic as the destination. A message can have the multiple consumer.

An email newsletter application may use the pub/sub model, where an interested candidate may become the subscriber to receive a new published message. The Java Virtual Machine Java Virtual Machine, which allows Java code to be executed on a wide variety of hardware and software environments. At the heart of the Java platform lies the Java Virtual Machine, or JVM. Most programming languages compile source code directly into machine code, suitable for execution on a particular microprocessor architecture. The difference with Java is that it uses bytecode - a special type of machine code. Java bytecode executes on a special type of microprocessor. Strangely enough, there wasn't a hardware implementation of this microprocessor available when Java was first released. Instead, the processor architecture is emulated by what is known as a "virtual machine". This virtual machine is an emulation of a real Java processor - a machine within a machine (Figure One). The only difference is that the virtual machine isn't running on a CPU - it is being emulated on the CPU of the host machine.

Figure One - JVM emulation run on a physical CPU The Java Virtual Machine is responsible for interpreting Java bytecode, and translating this into actions or operating system calls. For example, a request to establish a socket connection to a remote machine will involve an operating system call. Different operating systems handle sockets in different ways - but the programmer doesn't need to worry about such details. It is the responsibility of the JVM to handle these translations, so that the operating system and CPU architecture on which Java software is running is completely irrelevant to the developer.

Figure Two - JVM handles translations

The Java Virtual Machine forms part of a large system, the Java Runtime Environment (JRE). Each operating system and CPU architecture requires a different JRE. The JRE comprises a set of base classes, which are an implementation of the base Java API, as well as a JVM. The portability of Java comes from implementations on a variety of CPUs and architectures. Without an available JRE for a given environment, it is impossible to run Java software. Differences between JVM implementations Though implementations of Java Virtual Machines are designed to be compatible, no two JVMs are exactly alike. For example, garbage collection algorithms vary between one JVM and another, so it becomes impossible to know exactly when memory will be reclaimed. The thread scheduling algorithms are different between one JVM and another (based in part on the underlying operating system), so that it is impossible to accurately predict when one thread will be executed over another. Initially, this is a cause for concern from programmers new to the Java language. However, it actually has very little practical bearing on Java development. Such predictions are often dangerous to make, as thread scheduling and memory usage will vary between different hardware environments anyway. The power of Java comes from not being specific about the operating system and CPU architecture - to do so reduces the portability of software. Note : The Java Virtual Machine provides a platform-independent way of executing code, by abstracting the differences between operating systems and CPU architectures. Java Runtime Environments are available for a wide variety of hardware and software combinations, making Java a very portable language. Programmers can concentrate on writing software, without having to be concerned with how or where it will run. The idea of virtual machines is nothing new, but Java is the most widely used virtual machine used today. Thanks to the JVM, the dream of Write Once-Run Anywhere (WORA) software has become a reality. 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:

Users running programs: Built-in security functionality protects you from malevolent programs (including viruses), maintains the privacy of your files and information about you, and authenticates the identity of each code provider. You can subject applications and applets to security controls when you need to.

Developers:

You can use API methods to incorporate security functionality into your programs, including cryptography services and security checks. The API framework enables you to define and integrate your own permissions (controlling access to specific resources), cryptography service implementations, security manager implementations, and policy implementations. In addition, classes are provided for management of your public/private key pairs and public key certificates from people you trust.

Systems administrators, developers, and users: JDK tools manage your keystore (database of keys and certificates); generate digital signatures for JAR files, and verify the authenticity of such signatures and the integrity of the signed contents; and create and modify the policy files that define your installation's security policy.

Trail Lessons Quick Tour of Controlling Applets shows how resource accesses, such as reading or writing a file, are not permitted for unsigned applets unless explicitly allowed by a permission in a policy file. Quick Tour of Controlling Applications builds on the previous lesson, showing that when applications are run under a security manager, resource accesses may be controlled in exactly the same way as for unsigned applets. API and Tools Use for Secure Code and File Exchanges defines digital signatures, certificates, and keystores and discusses why they are needed. It also reviews information applicable to the next three lessons regarding the steps commonly needed for using the tools or the API to generate signatures, export/import certificates, and so on. Signing Code and Granting It Permissions illustrates the use of all the security-related tools. It shows the steps that a developer would take to sign and to distribute code for others to run. The lesson also shows how someone who will run the code (or a system administrator) could add an entry in a policy file to grant the code permission for the resource accesses it needs. Exchanging Files shows use of the tools by one person to sign an important document, such as a contract, and to export the public key certificate for the public key corresponding to the private key used to sign the contract. Then the lesson shows how another person, who receives the contract, the signature, and the public key certificate, can import the certificate and verify the signature. Generating and Verifying Signatures walks you step by step through an example of writing a Java program using the JDK Security API to generate keys, to generate a digital signature for data using the private key, and to export the public key and the signature to files. Then the example shows writing a second program, which may be expected to run on a different person's computer, that imports the public key and verifies the authenticity of the signature. Finally, the example discusses potential weaknesses of the approach used by the basic programs and demonstrates possible alternative approaches and methods of supplying and importing keys, including in certificates. Implementing Your Own Permission demonstrates how to write a class that defines its own special permission. Security functions help you to protect your programs and data from harm, to keep data shielded and private, and to deploy new applications in security-aware runtime environments.

Java also provides several tools to help you to manage access to system resources; to create, store and maintain encrypted public and private passwords (key pairs) and certificates; and to create and sign jarfiles during the deployment process. Java Security Overview 1 Introduction The Java platform was designed with a strong emphasis on security. At its core, the Java language itself is type-safe and provides automatic garbage collection, enhancing the robustness of application code. A secure class loading and verification mechanism ensures that only legitimate Java code is executed. The initial version of the Java platform created a safe environment for running potentially untrusted code, such as Java applets downloaded from a public network. As the platform has grown and widened its range of deployment, the Java security architecture has correspondingly evolved to support an increasing set of services. Today the architecture includes a large set of application programming interfaces (APIs), tools, and implementations of commonly-used security algorithms, mechanisms, and protocols. This provides the developer a comprehensive security framework for writing applications, and also provides the user or administrator a set of tools to securely manage applications. The Java security APIs span a wide range of areas. Cryptographic and public key infrastructure (PKI) interfaces provide the underlying basis for developing secure applications. Interfaces for performing authentication and access control enable applications to guard against unauthorized access to protected resources. The APIs allow for multiple interoperable implementations of algorithms and other security services. Services are implemented in providers, which are plugged into the Java platform via a standard interface that makes it easy for applications to obtain security services without having to know anything about their implementations. This allows developers to focus on how to integrate security into their applications, rather than on how to actually implement complex security mechanisms. The Java platform includes a number of providers that implement a core set of security services. It also allows for additional custom providers to be installed. This enables developers to extend the platform with new security mechanisms. This paper gives a broad overview of security in the Java platform, from secure language features to the security APIs, tools, and built-in provider services, highlighting key packages and classes where applicable. Note that this paper is based on Java SE version 7. 2 Java Language Security and Bytecode Verification The Java language is designed to be type-safe and easy to use. It provides automatic memory management, garbage collection, and range-checking on arrays. This reduces the overall programming burden placed on developers, leading to fewer subtle programming errors and to safer, more robust code. In addition, the Java language defines different access modifiers that can be assigned to Java classes, methods, and fields, enabling developers to restrict access to their class implementations as appropriate. Specifically, the language defines four distinct access levels: private, protected, public, and, if unspecified, package. The most open access specifier is public access is allowed to anyone. The most restrictive modifier is private access is not allowed outside the particular class in which the private member (a method, for example) is defined. The protected modifier allows access to any subclass, or to other classes within the same package. Package-level access only allows access to classes within the same package. A compiler translates Java programs into a machine-independent bytecode representation. A bytecode verifier is invoked to ensure that only legitimate bytecodes are executed in the Java runtime. It checks that the bytecodes conform to the Java Language Specification and do not violate

Java language rules or namespace restrictions. The verifier also checks for memory management violations, stack underflows or overflows, and illegal data typecasts. Once bytecodes have been verified, the Java runtime prepares them for execution. 3 Basic Security Architecture 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 into their application code. They were designed around the following principles: Implementation independence Applications do not need to implement security themselves. Rather, they can request security services from the Java platform. Security services are implemented in providers (see below), which are plugged into the Java platform via a standard interface. An application may rely on multiple independent providers for security functionality. Implementation interoperability Providers are interoperable across applications. Specifically, an application is not bound to a specific provider, and a provider is not bound to a specific application. Algorithm extensibility The Java platform includes a number of built-in providers that implement a basic set of security services that are widely used today. However, some applications may rely on emerging standards not yet implemented, or on proprietary services. The Java platform supports the installation of custom providers that implement such services. 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. Applications rely on the relevant getInstance method to obtain a security service from an underlying provider. For example, message digest creation represents one type of service available from providers. (Section 4 discusses message digests and other cryptographic services.) An application invokes the getInstance method in the java.security.MessageDigest class to obtain an implementation of a specific message digest algorithm, such as MD5. MessageDigest md = MessageDigest.getInstance("MD5"); The program may optionally request an implementation from a specific provider, by indicating the provider name, as in the following: MessageDigest md = MessageDigest.getInstance("MD5", "ProviderC"); Figures 1 and 2 illustrate these options for requesting an MD5 message digest implementation. Both figures show three providers that implement message digest algorithms. The providers are ordered by preference from left to right (1-3). In Figure 1, an application requests an MD5 algorithm implementation without specifying a provider name. The providers are searched in preference order and the implementation from the first provider supplying that particular algorithm, ProviderB, is returned. In Figure 2, the application requests the MD5 algorithm implementation from a specific provider, ProviderC. This time the implementation from that provider is returned, even though a provider with a higher preference order, ProviderB, also supplies an MD5 implementation.

Figure 1 Provider searching Figure 2 Specific provider requested The Java platform implementation from Oracle includes a number of pre-configured default providers that implement a basic set of security services that can be used by applications. Note that other vendor implementations of the Java platform may include different sets of providers that encapsulate vendor-specific sets of security services. When this paper mentions built-in default providers, it is referencing those available in Oracle's implementation. The sections below on the various security areas (cryptography, authentication, etc.) each include descriptions of the relevant services supplied by the default providers. A table in Appendix C summarizes all of the default providers. 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 where the Java Runtime Environment (JRE) is installed. Security properties may also be set dynamically by calling appropriate methods of the Security class (in the java.security package). 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

Message digest algorithms Digital signature algorithms Symmetric bulk encryption Symmetric stream encryption Asymmetric encryption

Password-based encryption (PBE) Elliptic Curve Cryptography (ECC) Key agreement algorithms Key generators Message Authentication Codes (MACs) (Pseudo-)random number generators

For historical (export control) reasons, the cryptography APIs are organized into two distinct packages. The java.security package contains classes that are not subject to export controls (like Signature and MessageDigest). The javax.crypto package contains classes that are subject to export controls (like Cipher and KeyAgreement). The cryptographic interfaces are provider-based, allowing for multiple and interoperable cryptography implementations. Some providers may perform cryptographic operations in software; others may perform the operations on a hardware token (for example, on a smartcard device or on a hardware cryptographic accelerator). Providers that implement export-controlled services must be digitally signed. The Java platform includes built-in providers for many of the most commonly used cryptographic algorithms, including the RSA, DSA, and ECDSA signature algorithms, the DES, AES, and ARCFOUR encryption algorithms, the MD5, SHA-1, and SHA-256 message digest algorithms, and the Diffie-Hellman and ECDH key agreement algorithms. These default providers implement cryptographic algorithms in Java code. The Java platform also includes a built-in provider that acts as a bridge to a native PKCS#11 (v2.x) token. This provider, named SunPKCS11, allows Java applications to seamlessly access cryptographic services located on PKCS#11-compliant tokens. On Windows, the Java platform includes a built-in provider that acts as a bridge to the native Microsoft CryptoAPI. This provider, named MSCAPI, allows Java applications to seamlessly access cryptographic services on Windows through the CryptoAPI. 5 Public Key Infrastructure Public Key Infrastructure (PKI) is a term used for a framework that enables secure exchange of information based on public key cryptography. It allows identities (of people, organizations, etc.) to be bound to digital certificates and provides a means of verifying the authenticity of certificates. PKI encompasses keys, certificates, public key encryption, aand trusted Certification Authorities (CAs) who generate and digitally sign certificates. The Java platform includes APIs 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. Key and Certificate Storage The Java platform provides for long-term persistent storage of cryptographic keys and certificates via key and certificate stores. Specifically, the java.security.KeyStore class represents a key store, a secure repository of cryptographic keys and/or trusted certificates (to be used, for example, during certification path validation), and the java.security.cert.CertStore class represents a certificate store, a public and potentially vast repository of unrelated and typically untrusted certificates. A CertStore may also store CRLs. KeyStore and CertStore implementations are distinguished by types. The Java platform includes the standard PKCS11 and PKCS12 key store types (whose implementations are compliant with the

corresponding PKCS specifications from RSA Security), as well as a proprietary file-based key store type called JKS (which stands for "Java Key Store"). The Java platform includes a special built-in JKS key store, cacerts, that contains a number of certificates for well-known, trusted CAs. The keytool utility is able to list the certificates included in cacerts (see the security features documentation link in Section 10). The SunPKCS11 provider mentioned in the "Cryptography" section (Section 4) includes a PKCS11 KeyStore implementation. This means that keys and certificates residing in secure hardware (such as a smartcard) can be accessed and used by Java applications via the KeyStore API. Note that smartcard keys may not be permitted to leave the device. In such cases, the java.security.Key object reference returned by the KeyStore API may simply be a reference to the key (that is, it would not contain the actual key material). Such a Key object can only be used to perform cryptographic operations on the device where the actual key resides. 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: keytool is used to create and manage key stores. It can

Create public/private key pairs Display, import, and export X.509 v1, v2, and v3 certificates stored as files Create self-signed certificates Issue certificate (PKCS#10) requests to be sent to CAs Create certificates based on certificate requests Import certificate replies (obtained from the CAs sent certificate requests) Designate public key certificates as trusted

The jarsigner tool is used to sign JAR files, or to verify signatures on signed JAR files. The Java ARchive (JAR) file format enables the bundling of multiple files into a single file. Typically a JAR file contains the class files and auxiliary resources associated with applets and applications. When you want to digitally sign code, you first use keytool to generate or import appropriate keys and certificates into your key store (if they are not there already), then use the jar tool to place the code in a JAR file, and finally use the jarsigner tool to sign the JAR file. The jarsigner tool accesses a key store to find any keys and certificates needed to sign a JAR file or to verify the signature of a signed JAR file. Note: jarsigner can optionally generate signatures that include a timestamp. Systems (such as Java Plug-in) that verify JAR file signatures can check the timestamp and accept a JAR file that was signed while the signing certificate was valid rather than requiring the certificate to be current. (Certificates typically expire annually, and it is not reasonable to expect JAR file creators to re-sign deployed JAR files annually.) 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). The Java platform provides APIs that enable an application to perform user authentication via pluggable login modules. Applications call into the LoginContext class (in the javax.security.auth.login package), which in turn references a configuration. The configuration

specifies which login module (an implementation of the javax.security.auth.spi.LoginModule interface) is to be used to perform the actual authentication. Since applications solely talk to the standard LoginContext API, they can remain independent from the underlying plug-in modules. New or updated modules can be plugged in for an application without having to modify the application itself. Figure 3 illustrates the independence between applications and underlying login modules:

Figure 3 Authentication login modules plugging into the authentication framework It is important to note that although login modules are pluggable components that can be configured into the Java platform, they are not plugged in via security Providers. Therefore, they do not follow the Provider searching model described in Section 3. Instead, as is shown in the above diagram, login modules are administered by their own unique configuration. The Java platform provides the following built-in LoginModules, all in the com.sun.security.auth.module package:

Krb5LoginModule for authentication using Kerberos protocols JndiLoginModule for username/password authentication using LDAP or NIS databases KeyStoreLoginModule for logging into any type of key store, including a PKCS#11 token key store

Authentication can also be achieved during the process of establishing a secure communication channel between two peers. The Java platform provides implementations of a number of standard communication protocols, which are discussed in the following section. 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. Cryptography forms the basis required for secure communication, and that is described in Section 4. The Java platform also provides API support and provider implementations for a number of standard secure communication protocols. 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 provide for the secure passage of data between two peers over any application protocol, such as HTTP on top of TCP/IP. The javax.net.ssl.SSLSocket class represents a network socket that encapsulates SSL/TLS support on top of a normal stream socket (java.net.Socket). Some applications might want to use alternate data transport abstractions (e.g., New-I/O); the javax.net.ssl.SSLEngine class is available to produce and consume SSL/TLS packets. 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. The Java platform includes a built-in provider that implements the SSL/TLS protocols:

SSLv3 TLSv1 TLSv1.1 TLSv1.2

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 javax.security.sasl.Sasl class is used to create SaslClient and SaslServer objects. SASL mechanism implementations are supplied in provider packages. Each provider may support one or more SASL mechanisms and is registered and invoked via the standard provider architecture. The Java platform includes a built-in provider that implements the following SASL mechanisms:

CRAM-MD5, DIGEST-MD5, EXTERNAL, GSSAPI, NTLM, and PLAIN client mechanisms CRAM-MD5, DIGEST-MD5, GSSAPI, and NTLM server mechanisms

GSS-API and Kerberos

The Java platform contains an API with the Java language bindings for the Generic Security Service Application Programming Interface (GSS-API). GSS-API offers application programmers uniform access to security services atop a variety of underlying security mechanisms. The Java GSS-API currently requires use of a Kerberos v5 mechanism, and the Java platform includes a built-in implementation of this mechanism. At this time, it is not possible to plug in additional mechanisms. Note: The Krb5LoginModule mentioned in Section 6 can be used in conjunction with the GSS Kerberos mechanism. The Java platform also includes a built-in implementation of the Simple and Protected GSSAPI Negotiation Mechanism (SPNEGO) GSS-API mechanism. Before two applications can use the Java GSS-API to securely exchange messages between them, they must establish a joint security context. The context encapsulates shared state information that might include, for example, cryptographic keys. Both applications create and use an org.ietf.jgss.GSSContext object to establish and maintain the shared information that makes up the security context. Once a security context has been established, it can be used to prepare secure messages for exchange. The Java GSS APIs are in the org.ietf.jgss package. The Java platform also defines basic Kerberos classes, like KerberosPrincipal, KerberosTicket, KerberosKey, and KeyTab, 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. Java applets and Java Web Start applications are automatically run with a SecurityManager installed. However, local applications executed via the java command are by default not run with a SecurityManager installed. In order to run local applications with a SecurityManager, either the application itself must programmatically set one via the setSecurityManager method (in the java.lang.System class), or java must be invoked with a -Djava.security.manager argument on the commandline. 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:

Where the code was loaded from Who signed the code (if anyone) Default permissions granted to the code This information is associated with the code regardless of whether the code is downloaded over an untrusted network (e.g., an applet) or loaded from the filesystem (e.g., a local application). The location from which the code was loaded is represented by a URL, the code signer is represented by the signer's certificate chain, and default permissions are represented by java.security.Permission objects. The default permissions automatically granted to downloaded code include the ability to make network connections back to the host from which it originated. The default permissions automatically granted to code loaded from the local filesystem include the ability to read files from the directory it came from, and also from subdirectories of that directory. 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. The Java platform encapsulates the notion of a security policy in the java.security.Policy class. There is only one Policy object installed into the Java runtime at any given time. The basic responsibility of the Policy object is to determine whether access to a protected resource is permitted to code (characterized by where it was loaded from, who signed it, and who is executing it). How a Policy object makes this determination is implementation-dependent. For example, it may consult a database containing authorization data, or it may contact another service. The Java platform includes a default Policy implementation that reads its authorization data from one or more ASCII (UTF-8) files configured in the security properties file. These policy files contain the exact sets of permissions granted to code: specifically, the exact sets of permissions granted to code loaded from particular locations, signed by particular entities, and executing as particular users. The policy entries in each file must conform to a documented proprietary syntax, and may be composed via a simple text editor or the graphical policytool utility. Access Control Enforcement The Java runtime keeps track of the sequence of Java calls that are made as a program executes. When access to a protected resource is requested, the entire call stack, by default, is evaluated to determine whether the requested access is permitted. As mentioned earlier, resources are protected by the SecurityManager. Security-sensitive code in the Java platform and in applications protects access to resources via code like the following: SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(perm); } where perm is the Permission object that corresponds to the requested access. For example, if an attempt is made to read the file /tmp/abc, the permission may be constructed as follows: Permission perm = new java.io.FilePermission("/tmp/abc", "read"); The default implementation of SecurityManager delegates its decision to the java.security.AccessController implementation. The AccessController traverses the call stack, passing to the installed security Policy each code element in the stack, along with the requested permission (for example, the FilePermission in the above example). The Policy determines whether the requested access is granted, based on the permissions configured by the administrator. If access is not granted, the AccessController throws a java.lang.SecurityException. Figure 4 illustrates access control enforcement. In this particular example, there are initially two elements on the call stack, ClassA and ClassB. ClassA invokes a method in ClassB, which then attempts to access the file /tmp/abc by creating an instance of java.io.FileInputStream. The FileInputStream constructor creates a FilePermission, perm, as shown above, and then passes perm to the SecurityManager's checkPermission method. In this particular case, only the permissions for ClassA and ClassB need to be checked, because all system code, including FileInputStream, SecurityManager, and AccessController, automatically receives all permissions. In this example, ClassA and ClassB have different code characteristics they come from different locations and have different signers. Each may have been granted a different set of permissions. The AccessController only grants access to the requested file if the Policy indicates that both classes have been granted the required FilePermission.

Figure 4 Controlling access to resources 9 XML Signature The Java XML Digital Signature API is a standard Java API for generating and validating XML Signatures. XML Signatures can be applied to data of any type, XML or binary (see http://www.w3.org/TR/xmldsig-core/). The resulting signature is represented in XML. An XML Signature can be used to secure your data and provide data integrity, message authentication, and signer authentication. The API is designed to support all of the required or recommended features of the W3C Recommendation for XML-Signature Syntax and Processing. The API is extensible and pluggable and is based on the Java Cryptography Service Provider Architecture. The Java XML Digital Signature APIs consist of six packages:

javax.xml.crypto javax.xml.crypto.dsig

javax.xml.crypto.dsig.keyinfo javax.xml.crypto.dsig.spec javax.xml.crypto.dom javax.xml.crypto.dsig.dom

JNDI Overview Naming and directory services play a vital role in intranets and the Internet by providing network-wide sharing of a variety of information about users, machines, networks, services, and applications. JNDI is an API specified in Java technology that provides naming and directory functionality to applications written in the Java programming language. It is designed especially for the Java platform using Java's object model. Using JNDI, applications based on Java technology can store and retrieve named Java objects of any type. In addition, JNDI provides methods for performing standard directory operations, such as associating attributes with objects and searching for objects using their attributes. JNDI is also defined independent of any specific naming or directory service implementation. It enables applications to access different, possibly multiple, naming and directory services using a common API. Different naming and directory service providers can be plugged in seamlessly behind this common API. This enables Java technology-based applications to take advantage of information in a variety of existing naming and directory services, such as LDAP, NDS, DNS, and NIS(YP), as well as enabling the applications to coexist with legacy software and systems. Using JNDI as a tool, you can build new powerful and portable applications that not only take advantage of Java's object model but are also well-integrated with the environment in which they are deployed. JNDI overview Use JNDI to better manage your distributed applications JNDI provides a common-denominator interface to many existing naming services. As such, JNDI was not designed to replace existing technology; instead, it provides a common interface to existing naming services. Let's begin by taking a look at some of these services. An introduction to naming services The figure below depicts the organization of a generic naming service.

A generic naming service A naming service maintains a set of bindings. Bindings relate names to objects. All objects in a naming system are named in the same way (that is, they subscribe to the same naming convention). Clients use the naming service to locate objects by name. There are a number of existing naming services, a few of which I'll describe below. They each follow the pattern above, but differ in the details.
o o

COS (Common Object Services) Naming: The naming service for CORBA applications; allows applications to store and access references to CORBA objects. DNS (Domain Name System): The Internet's naming service; maps people-friendly names (such as www.etcee.com) into computer-friendly IP (Internet Protocol) addresses in dotted-quad notation (207.69.175.36). Interestingly, DNS is a distributed naming service, meaning that the service and its underlying database is spread across many hosts on the Internet. LDAP (Lightweight Directory Access Protocol): Developed by the University of Michigan; as its name implies, it is a lightweight version of DAP (Directory Access Protocol), which in turn is part of X.500, a standard for network directory services. Currently, over 40 companies endorse LDAP. NIS (Network Information System) and NIS+: Network naming services developed by Sun Microsystems. Both allow users to access files and applications on any host with a single ID and password. Common features As I mentioned earlier, the primary function of a naming system is to bind names to objects (or, in some cases, to references to objects -- more on which in a moment). In order to be a naming service, a service must at the very least provide the ability to bind names to objects and to look up objects by name. Many naming systems don't store objects directly. Instead, they store references to objects. As an illustration, consider DNS. The address 207.69.175.36 is a reference to a computer's location on the Internet, not the computer itself. JNDI provides an interface that supports all this common functionality. I will present this interface later in this article. Their differences It's also important to understand how existing naming services differ, since JNDI must provide a workable abstraction that gets around those differences. Aside from functional differences, the most noticeable difference is the way each naming service requires names to be specified -- its naming convention. A few examples should illustrate the problem. In DNS, names are built from components that are separated by dots ("."). They read from right to left. The name "www.etcee.com" names a machine called "www" in the "etcee.com" domain. Likewise, the name "etcee.com" names the domain "etcee" in the top-level domain "com."

In LDAP, the situation is slightly more complicated. Names are built from components that are separated by commas (","). Like DNS names, they read from right to left. However, components in an LDAP name must be specified as name/value pairs. The name "cn=Todd Sundsted, o=ComFrame, c=US" names the person "cn=Todd Sundsted" in the organization "o=ComFrame, c=US." Likewise, the name "o=ComFrame, c=US" names the organization "o=ComFrame" in the country "c=US." As the examples above illustrate, a naming service's naming convention alone has the potential to introduce a significant amount of the flavor of the underlying naming service into JNDI. This is not a feature an implementation-independent interface should have. JNDI solves this problem with the Name class and its subclasses and helper classes. The Name class represents a name composed of an ordered sequences of subnames, and provides methods for working with names independent of the underlying naming service. A look at JNDI naming As I mentioned above, it's important to remember that JNDI is an interface rather than an implementation. This fact has some disadvantages -- you need access to an existing naming service (such as an LDAP service) and you need to understand something about how it works in order to play with JNDI. On the other hand, it does allow JNDI to integrate seamlessly into an existing computing environment where an established naming service holds sway. JNDI naming revolves around a small set of classes and a handful of operations. Let's take a look at them. Context and InitialContext The Context interface plays a central role in JNDI. A context represents a set of bindings within a naming service that all share the same naming convention. A Context object provides the methods for binding names to objects and unbinding names from objects, for renaming objects, and for listing the bindings. Some naming services also provide subcontext functionality. Much like a directory in a filesystem, a subcontext is a context within a context. This hierarchical structure permits better organization of information. For naming services that support subcontexts, the Context class also provides methods for creating and destroying subcontexts. JNDI performs all naming operations relative to a context. To assist in finding a place to start, the JNDI specification defines an InitialContext class. This class is instantiated with properties that define the type of naming service in use and, for naming services that provide security, the ID and password to use when connecting. For those of you familiar with the RMI Naming class, many of the methods provided by the Context interface outlined below will look familiar. Let's take a look at Context's methods:

void bind(String stringName, Object object): Binds a name to an object. The name must not be bound to another object. All intermediate contexts must already exist. void rebind(String stringName, Object object): Binds a name to an object. All intermediate contexts must already exist. Object lookup(String stringName): Returns the specified object. void unbind(String stringName): Unbinds the specified object.

The Context interface also provides methods for renaming and listing bindings.

void rename(String stringOldName, String stringNewName): Changes the name to which an object is bound. NamingEnumeration listBindings(String stringName): Returns an enumeration containing the names bound to the specified context, along with the objects and the class names of the objects bound to them. NamingEnumeration list(String stringName): Returns an enumeration containing the names bound to the specified context, along with the class names of the objects bound to them.

Each of these methods has a sibling that takes a Name object instead of a String object. A Name object represents a generic name. The Name class allows a program to manipulate names without having to know as much about the specific naming service in use. The example The example below illustrates how to connect to a naming service, list all of the bindings, or list a specific binding. It uses the filesystem service provider, which is one of the reference JNDI service-provider implementations provided by Sun. The filesystem service provider makes the filesystem look like a naming service (which it is, in many ways -- filenames like /foo/bar/baz are names and are bound to objects like files and directories). I selected it because everyone has access to a filesystem (as opposed to, say, an LDAP server). import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.Binding; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import java.util.Hashtable; public class Main { public static void main(String [] rgstring) { try { // Create the initial context. The environment // information specifies the JNDI provider to use // and the initial URL to use (in our case, a // directory in URL form -- file:///...). Hashtable hashtableEnvironment = new Hashtable(); hashtableEnvironment.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory" ); hashtableEnvironment.put( Context.PROVIDER_URL, rgstring[0] ); Context context = new InitialContext(hashtableEnvironment); // If you provide no other command line arguments, // list all of the names in the specified context and

// the objects they are bound to. if (rgstring.length == 1) { NamingEnumeration namingenumeration = context.listBindings(""); while (namingenumeration.hasMore()) { Binding binding = (Binding)namingenumeration.next(); System.out.println( binding.getName() + " " + binding.getObject() ); } } // Otherwise, list the names and bindings for the // specified arguments. else { for (int i = 1; i < rgstring.length; i++) { Object object = context.lookup(rgstring[i]); System.out.println( rgstring[i] + " " + object ); } } context.close(); } catch (NamingException namingexception) { namingexception.printStackTrace(); } } }

The program in the listing above first creates an initial context from the specified JNDI provider (in this case, Sun's filesystem provider) and a URL specifying a local directory. If no additional command-line arguments are specified, the program lists the objects and names of every entity in the specified directory. Otherwise, it lists the objects and names of only those items specified on the command line. Conclusion You should now have both an understanding of and an appreciation for naming services in general and JNDI in particular. In distributed environments, they are valuable tools for locating information and resources. JNDI makes it possible to work with a variety of naming services without having to master a multitude of APIs. Write native methods Here's a step-by-step recipe for writing and using native methods on the Linux platform : The ability to write just one set of code in Java and have it run on every system with a Java run-time is one of Java's primary strengths. But this platform independence has one key drawback: What do we do with the vast amount of existing code? The trick is to use the so-called native method interface. Writing native methods involves importing C code into your Java application. In this tip I'll walk you through the basic recipe for creating native methods and using them in a Java application.

Seven steps to native method - The steps to creating native methods are as follows:

Write Java code Compile Java code Create C header (.h file) Create C stubs file Write C code Create shared code library (or DLL) Run application Our exercise is to write some text to the console from inside the native method. The specifics of this example will be geared toward a Unix-like system, specifically Linux. I'll point out the couple of spots where the details differ for other platforms. Write Java code Write your Java code as you normally would. To use native methods in your Java code, you must do two things. First, write a native method declaration for each native method that you want to use. This is just like writing the declaration of a normal Java method interface, but you must specify the native keyword, as follows: public native void printText (); The second hoop to jump through is you must explicitly load the native code library. (We will create this later.) We do this by loading the library in a class static block: static { System.loadLibrary ("happy"); } To put these pieces together for our example, create a file called Happy.java with the following contents: class Happy { public native void printText (); static { System.loadLibrary ("happy"); /* Note lowercase of classname! */ } public static void main (String[] args) { Happy happy = new Happy (); happy.printText ();

} }

Compile Java code Compile the Happy.java file: % javac Happy.java

Create a C header file There are various magic incantations that must be made available so that our C code can be used as a native method. The javah functionality of the Java compiler will generate the necessary declarations and such from our Happy class. This will create a Happy.h file for us to include in our C code: % javah Happy Create a C stubs file In a manner reminiscent of the mangling that C++ translators do to the names of C++ methods, the Java compiler has a similar madness. To ease the pain of having to write a lot of tedious code so that our C code can be invoked from the Java run-time system, the Java compiler can generate the necessary trampoline code automatically for us: % javah -stubs Happy Write C code Now, let's write the actual code to print out our greeting. By convention we put this code in a file named after our Java class with the string "Imp" appended to it. This results in HappyImp.c. Place the following into HappyImp.c: #include &ltStubPreamble.h> /* Standard native method stuff. */ #include "Happy.h" /* Generated earlier. */ #include &ltstdio.h> /* Standard C IO stuff. */ void Happy_printText (struct HHappy *this) { puts ("Happy New Year!!!"); } In interfacing your C code with Java, many other aspects are involved -- such as how to pass and return the myriad types. For more information, see the Java tutorial or the Hermetica Native Methods Paper (see the Resources section for URLs). Create a shared library This section is the most system-dependent. It seems like every platform and each compiler/linker combination has a different method of creating and using shared libraries. For folks using any of the various Microsoft Windows platforms, check the documentation for your C compiler for the nitty-gritty details.

For you Linux folks, here's how to create a shared library using GCC. First, compile the C source files that we have already created. You have to tell the compiler where to find the Java native method support files, but the main trick here is that you have to explicitly tell the compiler to produce Position Independent Code: % gcc -I/usr/local/java/include -I/usr/local/java/include/genunix -fPIC -c Happy.c HappyImp.c Now, create a shared library out of the resulting object (.o) files with the following magical incantation: % gcc -shared -Wl,-soname,libhappy.so.1 -o libhappy.so.1.0 Happy.o HappyImp.o Copy the shared library file to the standard short name: % cp libhappy.so.1.0 libhappy.so Finally, you may need to tell your dynamic linker where to find this new shared library file. Using the bash shell: % export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH Execute the application Run the Java application as usual: % java Happy Well, that's all there is to it. Thanks to Tony Dering for passing on the Linux-specific incantations. A quick design note Before rushing off to write native methods for all of that legacy code, I would caution all of us to look carefully at the existing systems and see if there are better ways to connect them to Java. For instance, there are Java Database Connectivity (JDBC) and even higher-level solutions for accessing databases from Java. So, look at all of the tricks in your bag and use what makes sense for the project at hand. JavaMail Send and receive email with the JavaMail APIs In JavaMail you'll find APIs and provider implementations allowing you to develop fully functional email client applications. "Email client applications" invokes thoughts of Microsoft Outlook; and, yes, you could write your own Outlook replacement. But an email client need not reside on a client machine at all. Indeed, it could be a servlet or an EJB running on a remote server, providing end-user access to email via a Web browser. Think of Hotmail (yes, you could write your own version of Hotmail too). Or you could avoid a user interface altogether. How about an auto-responder that reads incoming messages and sends replies, customized according to the original sender? In my own pet project, a talking email client reads -- that is, speaks -- incoming messages. It's based on a refinement of an idea I introduced in "Talking Java!" I'll tell you more about it later. For now, start by installing and configuring the JavaMail software.

Setup If you use Java 2 Platform, Enterprise Edition (J2EE) 1.3, you're in luck: it includes JavaMail, so no additional setup is required. If, however, you're running Java 2 Platform, Standard Edition (J2SE) 1.1.7 and upwards, and you want email capability for your applications, download and install the following:

JavaMail JavaBeans Activation Framework

To install, simply unzip the downloaded files and add the contained jar files to your classpath. As an example, here's my classpath for this project: .;C:\Apps\Java\javamail-1.2\mail.jar;C:\Apps\Java \javamail-1.2\mailapi.jar;C:\Apps\Java\javamail-1.2 \pop3.jar;C:\Apps\Java\javamail-1.2\smtp.jar;C:\Apps \Java\jaf-1.0.1\activation.jar The mailapi.jar file contains the core API classes, while the pop3.jar and smtp.jar files contain the provider implementations for the respective mail protocols. (We won't use the imap.jar file in this article.) Think of the provider implementations as similar to JDBC (Java Database Connectivity) drivers, but for messaging systems rather than databases. As for the mail.jar file, it contains each of the above jar files, so you could restrict your classpath to just the mail.jar and activation.jar files. The activation.jar file allows you to handle MIME (Multipurpose Internet Mail Extensions) types accessible via binary data streams. Look for the DataHandler class in the Not Just Plain Text section later. For the record, the rest of this article does not offer comprehensive API coverage; rather, you will learn by doing. If it's in-depth API information you're looking for, then look at the PDF files and Javadocs included in the respective download bundles. Once you've installed the software, you need to get email account details to run the examples that follow. You'll need your ISP's SMTP (Simple Mail Transfer Protocol) server name and POP (Post Office Protocol) server name, your email account login name, and your mailbox password. Figure 1 shows my details -- not the real ones, you understand -- as used by Microsoft Outlook.

Figure 1. Tony's Internet mail settings

Sending email via SMTP The first example shows how to send a basic email message via SMTP. Below, you'll find the SimpleSender class, which takes your message's details from the command line and calls a separate method -- send(...) -- to send it: package com.lotontech.mail; import javax.mail.*; import javax.mail.internet.*; import java.util.*; /** * A simple email sender class. */ public class SimpleSender { /** * Main method to send a message given on the command line. */ public static void main(String args[]) { try

{ String smtpServer=args[0]; String to=args[1]; String from=args[2]; String subject=args[3]; String body=args[4]; send(smtpServer, to, from, subject, body); } catch (Exception ex) { System.out.println("Usage: java com.lotontech.mail.SimpleSender" +" smtpServer toAddress fromAddress subjectText bodyText"); } System.exit(0); } Next, run SimpleSender as below. Replace smtp.myISP.net with your own SMTP server, as derived from your mail settings: > java com.lotontech.mail.SimpleSender smtp.myISP.net bill@lotontech.com ben@lotontech.com "Hello" "Just to say Hello." And, if it works, at the receiving end you'll see something like what's shown in Figure 2.

Figure 2. Message received from SimpleSender The send(...) method completes the SimpleSender class. I'll show the code first, then detail the theory: /** * "send" method to send the message. */ public static void send(String smtpServer, String to, String from , String subject, String body) { try

{ Properties props = System.getProperties(); // -- Attaching to default Session, or we could start a new one -props.put("mail.smtp.host", smtpServer); Session session = Session.getDefaultInstance(props, null); // -- Create a new message -Message msg = new MimeMessage(session); // -- Set the FROM and TO fields -msg.setFrom(new InternetAddress(from)); msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to, false)); // -- We could include CC recipients too -// if (cc != null) // msg.setRecipients(Message.RecipientType.CC // ,InternetAddress.parse(cc, false)); // -- Set the subject and body text -msg.setSubject(subject); msg.setText(body); // -- Set some other header information -msg.setHeader("X-Mailer", "LOTONtechEmail"); msg.setSentDate(new Date()); // -- Send the message -Transport.send(msg); System.out.println("Message sent OK."); } catch (Exception ex) { ex.printStackTrace(); } } } First, notice that you're obtaining a mail session (java.mail.Session), without which you can do nothing. In this case you're calling Session.getDefaultInstance(...) to get a shared session, which other desktop applications may reuse; you can also set up an entirely new session -- via the Session.getInstance(...) method -- that would be unique to your application. The latter could prove important for email clients not isolated on a per-user basis, such as a Web-based email system implemented with servlets. Establishing a session requires you to set certain properties; at minimum, you need the mail.smtp.host property if you're sending messages via SMTP. import javax.mail.*; import javax.mail.internet.*; import java.util.*; import java.io.*; /**

* A simple email receiver class. */ public class SimpleReceiver { /** * Main method to receive messages from the mail server specified * as command line arguments. */ public static void main(String args[]) { try { String popServer=args[0]; String popUser=args[1]; String popPassword=args[2]; receive(popServer, popUser, popPassword); } catch (Exception ex) { System.out.println("Usage: java com.lotontech.mail.SimpleReceiver" +" popServer popUser popPassword"); } System.exit(0); } I'll take you through a proper test drive later, but for now here is the command line to run it (remember to replace the command arguments with your mail settings): > java com.lotontech.mail.SimpleReceiver pop.myIsp.net myUserName myPassword The receive(...) method -- called from main(...) -- opens your POP3 INBOX and steps through the messages in turn, each time calling printMessage(...). Here is the code: /** * "receive" method to fetch messages and process them. */ public static void receive(String popServer, String popUser , String popPassword) { Store store=null; Folder folder=null; try { // -- Get hold of the default session -Properties props = System.getProperties();

Session session = Session.getDefaultInstance(props, null); // -- Get hold of a POP3 message store, and connect to it -store = session.getStore("pop3"); store.connect(popServer, popUser, popPassword); // -- Try to get hold of the default folder -folder = store.getDefaultFolder(); if (folder == null) throw new Exception("No default folder"); // -- ...and its INBOX -folder = folder.getFolder("INBOX"); if (folder == null) throw new Exception("No POP3 INBOX"); // -- Open the folder for read only -folder.open(Folder.READ_ONLY); // -- Get the message wrappers and process them -Message[] msgs = folder.getMessages(); for (int msgNum = 0; msgNum < msgs.length; msgNum++) { printMessage(msgs[msgNum]); } } catch (Exception ex) { ex.printStackTrace(); } finally { // -- Close down nicely -try { if (folder!=null) folder.close(false); if (store!=null) store.close(); } catch (Exception ex2) {ex2.printStackTrace();} } } Notice that you're obtaining a POP3 message-store wrapper from the session, then connecting to it using the mail settings originally supplied on the command line. Once connected, you get a handle on the default folder -- effectively the root of the folder tree -- and, from there, the INBOX folder that holds the inbound messages. You open the INBOX for read-only access; you get hold of the messages and step through them one by one.

As an aside, you might wonder if you would ever want to open the INBOX for write access. You would if you intended to mark the messages as received and/or remove them from the server. In our example, you're only looking at them. Finally, in the code above you're taking care to close the folder and the message store when finished, which leaves only the printMessage(...) method to complete this class. Print the messages In this section, the earlier javax.mail.Part interface discussion becomes relevant. In the code that follows you will see how to implicitly cast the message to its Part interface and assign it to the messagePart variable. For single-part messages you now have something to print. If a call to messagePart.getContent() yields a Multipart instance, you know you're dealing with a multipart message; in that case, you're getting hold of the first multipart -- via getBodyPart(0) -- and printing it. Whether you've got a hold of the message itself, or only the first body part, you're printing it only if the content is plain text or HTML, and you're doing so by reading from an InputStream: /** * "printMessage()" method to print a message. */ public static void printMessage(Message message) { try { // Get the header information String from=((InternetAddress)message.getFrom()[0]).getPersonal(); if (from==null) from=((InternetAddress)message.getFrom()[0]) .getAddress(); System.out.println("FROM: "+from); String subject=message.getSubject(); System.out.println("SUBJECT: "+subject); // -- Get the message part (i.e. the message itself) -Part messagePart=message; Object content=messagePart.getContent(); // -- or its first body part if it is a multipart message -if (content instanceof Multipart) { messagePart=((Multipart)content).getBodyPart(0); System.out.println("[ Multipart Message ]"); } // -- Get the content type -String contentType=messagePart.getContentType(); // -- If the content is plain text, we can print it -System.out.println("CONTENT:"+contentType); if (contentType.startsWith("text/plain") || contentType.startsWith("text/html")) {

InputStream is = messagePart.getInputStream(); BufferedReader reader =new BufferedReader(new InputStreamReader(is)); String thisLine=reader.readLine(); while (thisLine!=null) { System.out.println(thisLine); thisLine=reader.readLine(); } } System.out.println("-----------------------------"); } catch (Exception ex) { ex.printStackTrace(); } }} For simplicity I've assumed that the message itself, or the first body part, is printable. For any real application, you would want to step through every body part in turn and for each one take some appropriate action -- print it or save it to disk, depending on the content type. As you fetch each message from the message store, you're actually getting hold of a lightweight wrapper. The data content itself is fetched using a lazy approach, at the time you ask for it -- useful if you wish to download only the message headers initially. SimpleReceiver test drive Let's take the SimpleReceiver for a test drive. To give it something to receive, I sent out the message illustrated in Figure 4 (notice that the message comprises text and an attachment).

Figure 4. Test message for SimpleReceiver Upon reception it was identified as a multipart message. The text printed as: FROM: Tony Loton SUBJECT: Number 1 [ Multipart Message ] CONTENT:text/plain; charset="iso-8859-1" Attachment 1 from Tony Loton. -----------------------------

Speak the messages For a bit of fun, and to demonstrate a novel use of the JavaMail APIs, I now briefly turn to my talking email project. To try this out you'll need the lotontalk.jar file (supplied), and you'll need to include it in your classpath, as in:
set CLASSPATH=%CLASSPATH%;lotontalk.jar

What is Struts? Struts is a framework that promotes the use of the Model-View-Controller architecture for designing large scale applications. The framework includes a set of custom tag libaries and their associated Java classes, along with various utility classes. The most powerful aspect of the Struts framework is its support for creating and processing web-based forms. We will see how this works later in this chapter.

Struts Tags Common Attributes Almost all tags provided by the Struts framework use the following attributes: Attribute Used for id name property scope the name of a bean for temporary use by the tag the name of a pre-existing bean for use with the tag the property of the bean named in the name attribute for use with the tag the scope to search for the bean named in the name attribute

What Is the Struts Framework? The Struts Framework is a standard for developing well-architected Web applications. It has the following features: Open source Based on the Model-View-Controller (MVC) design paradigm, distinctly separating all three levels: o Model: application state o View: presentation of data (JSP, HTML) o Controller: routing of the application flow Implements the JSP Model 2 Architecture Stores application routing information and request mapping in a single core file, struts-config.xml The Struts Framework, itself, only fills in the View and Controller layers. The Model layer is left to the developer. Architecture Overview

All incoming requests are intercepted by the Struts servlet controller. The Struts Configuration file strutsconfig.xml is used by the controller to determine the routing of the flow. This flows consists of an alternation between two transitions:

From View to Action A user clicks on a link or submits a form on an HTML or JSP page. The controller receives the request, looks up the mapping for this request, and forwards it to an action. The action in turn calls a Model layer (Business layer) service or function. From Action to View After the call to an underlying function or service returns to the action class, the action forwards to a resource in the View layer and a page is displayed in a web browser. The diagram below describes the flow in more detail:

1. User clicks on a link in an HTML page. 2. Servlet controller receives the request, looks up mapping information in strutsconfig.xml, and routes to an action. 3. 4. 5. 6. 7. Action makes a call to a Model layer service. Service makes a call to the Data layer (database) and the requested data is returned. Service returns to the action. Action forwards to a View resource (JSP page) Servlet looks up the mapping for the requested resource and forwards to the appropriate JSP page. 8. JSP file is invoked and sent to the browser as HTML. 9. User is presented with a new HTML page in a web browser. Struts Components The Controller This receives all incoming requests. Its primary function is the mapping of a request URI to an action class selecting the proper application module. It's provided by the framework.

The struts-config.xml File This file contains all of the routing and configuration information for the Struts application. This XML file needs to be in the WEB-INF directory of the application. Action Classes It's the developer's responsibility to create these classes. They act as bridges between user-invoked URIs and business services. Actions process a request and return an ActionForward object that identifies the next component to invoke. They're part of the Controller layer, not the Model layer. View Resources View resources consist of Java Server Pages, HTML pages, JavaScript and Stylesheet files, Resource bundles, JavaBeans, and Struts JSP tags. ActionForms These greatly simplify user form validation by capturing user data from the HTTP request. They act as a "firewall" between forms (Web pages) and the application (actions). These components allow the validation of user input before proceeding to an Action. If the input is invalid, a page with an error can be displayed. Model Components The Struts Framework has no built-in support for the Model layer. Struts supports any model components: JavaBeans EJB CORBA JDO

any other

S-ar putea să vă placă și