Professional Documents
Culture Documents
Before we start examining the details of using RMI, let's look at a simple RMI remote object at work. We can
create an Account object that represents some kind of bank account and then use RMI to export it as a remote
object so that remote clients (e.g., ATMs, personal finance software running on a PC) can access it and carry
out transactions.
The first step is to define the interface for our remote object. Example 3-1 shows the Account interface. You
can tell that it's an RMI object because it extends the java.rmi.Remote interface. Another signal that this is
meant for remote access is that each method can throw a java.rmi.RemoteException. The Account interface
includes methods to get the account name and balance and to make deposits, withdrawals, and transfers.
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.List;
The next step is to create an implementation of this interface, which leads to the AccountImpl class shown in
Example 3-2. This class implements all the methods listed in the Account interface and adds a constructor that
takes the name of the new account to be created. Notice that the AccountImpl class implements the Account
interface, but it also extends the java.rmi.UnicastRemoteObject class. This RMI class provides some of the
basic remote functionality for server objects.
Example 3-2. Implementation of the Remote Account Interface
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;
import java.util.List;
import java.util.ListIterator;
// Move some funds from another (remote) account into this one
public void transfer(float amt, Account src) throws RemoteException {
src.withdraw(amt);
this.deposit(amt);
}
// Make several transfers from other (remote) accounts into this one
public void transfer(List amts, List srcs) throws RemoteException {
ListIterator amtCurs = amts.listIterator();
ListIterator srcCurs = srcs.listIterator();
// Iterate through the accounts and the amounts to be transferred from
// each (assumes amounts are given as Float objects)
while (amtCurs.hasNext() && srcCurs.hasNext()) {
Float amt = (Float)amtCurs.next();
Account src = (Account)srcCurs.next();
this.transfer(amt.floatValue(), src);
Once the remote interface and an implementation of it are complete, you need to compile both Java files with
your favorite Java compiler. After this is done, you use the RMI stub/skeleton compiler to generate a client stub
and a server skeleton for the AccountImpl object. The stub and skeleton handle the communication between the
client application and the server object. With Sun's Java SDK, the RMI compiler is called RMIC, and you can
invoke it for this example like so:
% rmic -d /home/classes AccountImpl
The stub and skeleton classes are generated and stored in the directory given by the -d option (/HOME/CLASSES,
in this case). This example assumes that the AccountImpl class is already in your CLASSPATH before you run
the RMI compiler.
There's just one more thing we need to do before we can actually use our remote object: register it with an RMI
registry, so that remote clients can find it on the network. The utility class that follows, RegAccount, does this
by creating an AccountImpl object and then binding it to a name in the local registry using the
java.rmi.Naming interface. After it's done registering the object, the class goes into a wait(), which allows
remote clients to connect to the remote object:
import java.rmi.Naming;
public class RegAccount {
public static void main(String argv[]) {
try {
// Make an Account with a given name
AccountImpl acct = new AccountImpl("JimF");
}
}
}
After you compile the RegAccount class, you can run its main() method to register an Account with the local
RMI registry. First, however, you need to start the registry. With Sun's Java SDK, the registry can be started
using the RMIREGISTRY utility. On a Unix machine, this can be done like so:
objhost% rmiregistry &
Account object:
import java.rmi.Naming;
// Make deposit
jimAcct.deposit(12000);
Now that we've seen a complete example of an RMI object in action, let's look at what makes remote objects
work, starting with an overview of the underlying RMI architecture. There are three layers that comprise the
basic remote-object communication facilities in RMI:
The STUB/SKELETON layer, which provides the interface that client and server application objects use to
interact with each other.
The REMOTE REFERENCE layer, which is the middleware between the stub/skeleton layer and the underlying
transport protocol. This layer handles the creation and management of remote object references.
The TRANSPORT PROTOCOL layer, which is the binary data protocol that sends remote object requests over the
wire.
These layers interact with each other as shown in Figure 3-1. In this figure, the server is the application that
provides remotely accessible objects, while the client is any remote application that communicates with these
server objects.
In a distributed object system, the distinctions between clients and servers can get pretty blurry at times.
Consider the case where one process registers a remote-enabled object with the RMI naming service, and a
number of remote processes are accessing it. We might be tempted to call the first process the server and the
other processes the clients. But what if one of the clients calls a method on the remote object, passing a
reference to an RMI object that's local to the client. Now the server has a reference to and is using an object
exported from the client, which turns the tables somewhat. The "server" is really the server for one object and
the client of another object, and the "client" is a client and a server, too. For the sake of discussion, I'll refer to a
process in a distributed application as a server or client if its role in the overall system is generally limited to
one or the other. In peer-to-peer systems, where there is no clear client or server, I'll refer to elements of the
system in terms of application-specific roles (e.g., chat participant, chat facilitator).
As you can see in Figure 3-1, a client makes a request of a remote object using a client-side stub; the server
object receives this request from a server-side object skeleton. A client initiates a remote method invocation by
calling a method on a stub object. The stub maintains an internal reference to the remote object it represents and
forwards the method invocation request through the remote reference layer by MARSHALLING the method
arguments into serialized form and asking the remote reference layer to forward the method request and
arguments to the appropriate remote object. Marshalling involves converting local objects into portable form so
that they can be transmitted to a remote process. Each object is checked as it is marshaled, to determine whether
it implements the java.rmi.Remote interface. If it does, its remote reference is used as its marshaled data. If it
isn't a Remote object, the argument is serialized into bytes that are sent to the remote host and reconstituted into
a copy of the local object. If the argument is neither Remote nor Serializable, the stub throws a
java.rmi.MarshalException back to the client.
If the marshalling of method arguments succeeds, the client-side remote reference layer receives the remote
reference and marshaled arguments from the stub. This layer converts the client request into low-level RMI
transport requests according to the type of remote object communication being used. In RMI, remote objects
can (potentially) run under several different communication styles, such as point-to-point object references,
The remote object activation service is new to RMI as of Version 1.2 of the Java 2 platform. It provides a way
for server objects to be started on an as-needed basis. Without remote activation, a server object has to be
The last of the remote object services, distributed garbage collection, is a fairly automatic process that you as an
application developer should never have to worry about. Every server that contains RMI-exported objects
automatically maintains a list of remote references to the objects it serves. Each client that requests and receives
a reference to a remote object, either explicitly through the registry/naming service or implicitly as the result of
a remote method call, is issued this remote object reference through the remote reference layer of the object's
host process. The reference layer automatically keeps a record of this reference in the form of an expirable
"lease" on the object. When the client is done with the reference and allows the remote stub to go out of scope,
or when the lease on the object expires, the reference layer on the host automatically deletes the record of the
remote reference and notifies the client's reference layer that this remote reference has expired. The concept of
expirable leases, as opposed to strict on/off references, is used to deal with situations where a client-side failure
or a network failure keeps the client from notifying the server that it is done with its reference to an object.
When an object has no further remote references recorded in the remote reference layer, it becomes a candidate
for garbage collection. If there are also no further local references to the object (this reference list is kept by the
Java VM itself as part of its normal garbage-collection algorithm), the object is marked as garbage and picked
up by the next run of the system garbage collector.
Q. 2 Write the steps in creating and running applets in Java along with a sample program to demonstrate the
same. Also describe various ways of running Applets.
ANS:-
A Java applet is an applet delivered to the users in the form of Java bytecode. Java applets can run in a Web
browser using a Java Virtual Machine (JVM), or in Sun's AppletViewer, a stand-alone tool for testing applets.
Java applets were introduced in the first version of the Java language in 1995. Java applets are usually written in
the Java programming language but they can also be written in other languages that compile to Java bytecode
such as Jython,[8] JRuby,[9] or Eiffel (via SmartEiffel).[10]
Applets are used to provide interactive features to web applications that cannot be provided by HTML alone.
They can capture mouse input (like rotating 3D object) and also have controls like buttons or check boxes. In
Q. 3 Create a User Interface to perform arithmetic operations to demonstrate event handling mechanisms.
ANS:- The JavaFX Script programming language enables you to make a desktop or a mobile application respond in a
preprogrammed way to events through a convenient event-handling mechanism. Each JavaFX object that can potentially
expose behavior has instance variables that map to event-related functions. You can define these functions to handle
events such as the click of a mouse button, tap of a stylus, or the release of a key. For example, you can define a function
that will render text when you click a circle with your mouse. For a complete list of events that can be handled by objects,
see the JavaFX Script API.
The following screen captures show all the possible button states.
Create a file with an .fx extension, for example Events.fx. Avoid using file names that match the names of existing
classes, instance variables, or reserved words because this type of naming leads to errors during compilation. For more
information about existing classes, variables, and reserved words, see JavaFX Script API and Learning the JavaFX Script
Programming Language.
Adding Graphics
All button states are available in the following PNG images: play_onMouseExited.png, play_onMousePressed.png,
stop_onMouseExited.png, and stop_onMousePressed.png. To use the images as scene objects, use a combination of the
Image and ImageView classes.
When specifying the image url, you can set the URI of the resource or use the relative codebase. In this example, the
image url is set by using the __DIR__ variable that indicates the directory where the image is located. By default it points
to the current directory, so ensure that the images are located in the same directory as application-compiled classes. To run
the application on the mobile emulator ensure that the images are packed into the application jar file along with the
compiled classes.
Define the image variable to store an image of the current button state, and set it to the initial state, playNormal.
Define the button variable to the a scene object corresponding to the current state of the button, and bind it to the image
variable.
Specify the scene of the application and add the button to its content.
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.Group;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
Stage {
title: "Play Button"
scene: Scene {
width: 300
height: 240
content: Group {
content: button
}
}
}
Note: The button is added to the Group construct for further application enhancements. In your application you can add an
ImageView object directly to the scene content..
var X: Number;
var Y: Number;
onMousePressed: function(event) {
As a result, the button changes its appearance when you press it depending on the mode of the button.
Handling the Release Event
The release event occurs when you release a mouse pointer from the button. In this example, when you release the pointer
from the button, it switches its mode.
To handle the mouse release event, use the following code:
onMouseReleased: function(event) {
if (mode){
image = stopNormal;
mode = false;
} else {
image = playNormal;
mode = true;
}
}
After an image is changed, the mode variable changes its value to the opposite. At this point, the application implements
switching between the Play and Stop modes and changing the button appearance on the mouse press. The next section
concerns dragging the button within the scene.
Handling the Drag Event
Unlike the mouse events mentioned in the previous sections, the onMouseDragged event does not change the button's
appearance. This event enables you to alter the button position dragging it when the mouse is pressed. In this example,
you cannot move the button beyond the bounds of the scene.
Use the following code fragment to handle the drag event:
onMouseDragged: function(event) {
if (event.sceneX - X <0) {
event.node.translateX = 0;
} else { if (event.sceneX - X > 300 - image.width){
event.node.translateX = 300 - image.width;
} else {
event.node.translateX = event.sceneX - X;
}
}
Two if constructions are used to check whether the button has been dragged outside of the scene, and to set values for the
translateX and translateY variables of the button. Consider an example when the drag event occurred at the point (320,
100). Suppose that the X was fixed as 5, and the Y was fixed as 10. Then the event.node.translateX - X = 320 - 5 = 315,
while 300 - image.width = 300 -63 = 237. The value 315 is greater than 237, so the translateX variable will be set to 300 -
image.width = 237, and the button will be placed at the right border of the scene. The translateY variable will be set to
event.sceneY - Y = 100 - 10 = 90. Therefore, the button will be moved to the following position: translateX = 237,
translateY = 90.
The following screen capture shows the application run on the Touch Phone emulator.
You can find the complete code of this application in the EventsCommon.fx file. The next section discusses how to handle
some additional desktop-specific events.
Desktop Profile
- Adding Tooltips
- Handling the Mouse-Enter Event
In this section, you will learn how to enhance the existing example by using additional features specific for desktop
applications. Consider handling the mouse-enter and mouse-exit events by changing the button's appearance when the
mouse pointer is on it. In addition, the modified application will show two variants of tooltips depending in the mode of
the button. Try the following applet to evaluate event handling. Hover, press, release, and drag the button.
Two new images represent the button's state: play_onMouseEntered.png and stop_onMouseEntered.png. So you need to
define two more Image variables.
Adding Tooltips
Perform the following steps to create a textual tooltip and add it to the scene.
Add import statements for the Text, Font, Timeline, and Color classes.
Declare a Text object specifying the string to render, the color, and the position of the tooltip. Set the content variable
depending on the current mode of the button. Set "Play Button" when the button is in Play mode, and "Stop Button"
otherwise. Also bind the translateX and translateY variables to the corresponding variables of the button object.
Add the tooltip object to the scene.
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.Group;
import javafx.animation.Timeline;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
Stage {
title: "Play Button"
scene: Scene {
fill: Color.WHITE
width: 300
height: 240
content: Group {
content: [button, tooltip]
}
}
...
onMouseEntered: function(event) {
image = if (mode){
playHover;
} else {
stopHover
}
appear.rate = 1;
appear.play();
}
When the mouse pointer exits the area defined by the graphic button, the button's appearance returns to its initial state.
The tooltip disappears, because the rate variable of the animation timeline is set to -1 and the tooltip opacity alters from
1.0 to 0.0.
For more information about the onMouseExited function, see JavaFX Script API.
Here is the complete Events.fx file.
Architecture Digram:
The following figure depicts a typical servlet life-cycle scenario.
First the HTTP requests coming to the server are delegated to the servlet container.
The servlet container loads the servlet before invoking the service() method.
Then the servlet container handles multiple requests by spawning multiple threads, each thread executing the service() method of a single instance of the
servlet
Q.5. Explain the importance of CORBA and its applications in running client server programs.
ANS:
Exceptions in CORBA IDL: CORBA IDL allows exceptions to be defined in interfaces and thrown by their ethods. To
illustrate this point, we have defined our list of shapes inthe server as a sequence of a fixed length (line 4) and have
defined FullException (line6), which is thrown by the method newShape (line 7) if the client attempts to add a shape when
the sequence is full.
Invocation semantics: Remote invocation in CORBA has at-most-once call semantics as the default. However, IDL may
specify that the invocation of a particular method has maybe semantics by using the oneway keyword. The client does not
block on oneway requests, which can be used only for methods without results. For an example of a
oneway request, see the example on callbacks at the end of Section 17.2.1.
The CORBA Naming service
◊ The CORBA Naming Service is discussed in Section
17.3.1. It is a binder that provides operations including rebind for servers to register the
remote object references of CORBA objects by name and resolve for clients to look them up by name. The names are
structured in a hierarchic fashion, and each name in a path is inside a structure called a NameComponent. This makes
access in a simple example seem rather complex.
CORBA pseudo objects (Jaa 2 version 1.4) ◊ Implementations of CORBA provide some interfaces to the functionality of
the ORB that programmers need to use. They are called pseudo-objects because they cannot be used like CORBA objects;
for example, they cannot be passed as arguments in RMIs. They have IDL interfaces and are implemented as libraries.
Those relevant to our simple example are:
• The ORB interface includes: The method init, which must be called to initialize the ORB; the method
resolve_initial_references, which is used to find services such as the Naming Service and the root POA; other methods,
which enable conversions between remote object references and strings.
• The POA (Portable Object Adaptor – see Figure 17.6 and page 678) interface includes: A method for activating a
POAmanager; a method servant_to_reference for registering a CORBA object.
This section outlines the steps necessary to produce client and server programs that use the IDL Shape and ShapeList
interfaces shown in Figure 17.1. This is followed by a discussion of callbacks in CORBA. We use Java as the client and
AJAX uses XHTML for the data presentation of the view layer, DOM, short for Document Object Model, which
dynamically manipulates the presentation, XML for data exchange, and XMLHttpRequest as the exchange engine that
ties everything together.
Because of these requirements, AJAX works on I.E. 5.0+, Mozilla 1.0+, Firefox 1.0+, Netscape 7.0+, and Apple
added it to Safari 1.2+.
Traditional HTML sends a request to the server, which processes it and either returns a static HTML page or
dispatches the request to some scripting language such as ColdFusion, which creates and returns an HTML page for
the browser to render. When this method has to retrieve new data from the server it has to repost and reload
another HTML file. In many cases perhaps only a small portion of the returned HTML code varies and the shell itself
remains the same resulting in huge overhead because the data has to be downloaded every time.
Some classic examples of applications that would benefit from AJAX are searching for information and displaying it
back in a table, related select dropdowns, or checking if a user exists before submitting an entire form.
As we can see, AJAX offers many advantages over traditional HTML applications, but we shouldn't overestimate it.
Because the data is JavaScript-driven, one of the main drawbacks is that search engines won't index any of the
dynamically generated content. It's definitely not SEO-friendly.
People familiar with MVC will have a better grasp of the concept. Though details of MVC are outside of the scope of
this article, the three defined components are Model, View, and Controller. The controller mediates between the data
model and the view. It responds to events, which are usually actions by users, and changes the view or model as
appropriate. The view consists of the HTML. JavaScript reacts to events triggered by the user and alters the existing
rendered content with DOM. ColdFusion will be our model layer and can consist of one or more files.
Building an AJAX platform or engine from scratch can be a difficult and lengthy procedure. There are many AJAX
engines available for download and you're welcome to use any of them. The only difference between implementations
will be the data encoding, transmission, and decoding methods. The views and models of the MVC will be the same.
My examples will be based on CFAJAX, a community-driven Open Source project. One of the problems with CFAJAX is
its poor documentation. There is no manual or even a complete FAQ. So I will explain how to set it up step-by-step
and work around its downside.
To use AJAX you'll need to really know JavaScript and DOM. But by the end of this article you'll be able to set up
AJAX, a ColdFusion model, make basic calls, and exchange simple data. As the applications grow and become more
complex, the AJAX engine will remain the same, and the CF model will have more functions, but your JavaScript will
have to manipulate more and more objects and that's where it's really at.