Copy Link
Add to Bookmark
Report
Java Coffee Break Newsletter Volume 1 Issue 05
Java Coffee Break Newsletter Vol 1, Issue 5
ISSN 1442-3790
Welcome to the fifth Java Coffee Break Newsletter. This issue is
packed full of information for Java developers. There's coverage of
the new CORBA support in Java 1.2, and an introduction to Remote
Method Invocation (RMI), and more answers to commonly asked Java
questions.
- - - - - - - - - - - - - - - - - - - - - - - -
Java Coffee Break Updates
* Free Articles & Tutorials
* Programming Tools
* Q&A : How do I create a scrollable container?
* Q&A : How do I convert from an int to a char?
* Java and CORBA - a smooth blend
* Introduction to RMI
1. Free Articles & Tutorials
We've got free articles and tutorials about Java that teach basic
programming concepts, right through to advanced topics like
networking, JavaBeans & CORBA.
For more information, visit the Java Coffee Break at
http://www.davidreilly.com/jcb/
2. Programming Tools
If you're looking for programming tools, check out the great
savings available from Beyond.Com, the software superstore.
http://www.beyond.com/AF10445/departments/programming/programming.htm
- - - - - - - - - - - - - - - - - - - - - - - - -
Q&A : How do I create a scrollable container?
The good news is there is already a scrollable container as part of the
java.awt package. It's called ScrollPane, and without this, you'd need
to create one from scratch, using scrollbars. Phew!
Its easy to create an instance of ScrollPane, and to then add it to your
applet or application. Simply create a new instance of ScrollPane, and
then add it to your applet's canvas. Whatever size your applet is, the
scroll pane will adjust to. Now as you add components, scroll bars will
appear as needed. You can also change the size of the scrollbar via the
setSize() method. Here's a quick example
// Create a scroll pane object
ScrollPane myContainer = new ScrollPane();
// Add scroll pane to my current canvas (if I am an applet)
add(myContainer);
// Now I can add components to my container......
- - - - - - - - - - - - - - - - - - - - - - - - -
Q&A : How do I convert from an int to a char?
If you aren't interested in converting from an int to a string (from int
127 to string "127"), and only want to convert to an ASCII value, then
you only need to cast from an int to a char.
What's casting? Casting is when we explicitly convert from one primitve
data type, or a class, to another. Here's a brief example.
public class int_to_char
{
public static void main(String args[])
{
int a = 65;
char myChar = (char) a; // cast from int to char
System.out.println ("Char - " + myChar);
}
}
In this example, we have a number (65), which represents ASCII character
A. We cast the number from an integer to a char, converting it to the
letter A. You could also reverse the cast if needed (converting the
ASCII char into a number).
- - - - - - - - - - - - - - - - - - - - - - - - -
Java and CORBA - a smooth blend
By David Reilly
With the introduction of support for CORBA into Java 1.2, developers can
now create distributed systems that run in a hybrid mix of Java and
other CORBA-friendly languages. Java 1.2 includes everything you need
to start writing CORBA services. In this article, I'll show you how to
get started with Java IDL.
What is CORBA?
CORBA, for those who haven't heard of it before, stands for Common
Object Request Broker Architecture. This architecture allows clients
to invoke methods of objects running on remote servers. The idea is
nothing new - many developers will have come across similar systems
such as RPC (remote procedure call), or Java's own RMI (remote method
invocation). The difference between these and CORBA is that CORBA is
much more interoperable with other platforms - a C++ object running on
a Wintel system can communicate with a Java object on a Unix box.
Developers don't need to know what language a CORBA service is written
in, or even where it is physically located. This makes CORBA systems
very versatile - one can change the location of a CORBA object, and
then re-register with a nameserver. Clients that look up the service
can then find its new location, and then continue to make requests.
Java makes it easy to integrate support for CORBA into applications
and applets, thanks to the introduction of Java IDL in JDK1.2
Interface Definition Language (IDL)
Developers use the Interface Definition Language (IDL) to describe the
interface to a CORBA object. An IDL schema can then be used to generate
Java code for the client and server that will use the object. The same
IDL schema could be used to generate either a client or server in C++,
Ada, or any other language that supports CORBA. You don't write your
implementation of a CORBA service in IDL - so you can continue to write
in pure Java code if you so wish.
Let's start by taking a look at a sample IDL schema, to give you an
idea what I'm talking about. The following schema shows a very simple
CORBA service, which allows clients to get and store the name
associated with an email address. For the purposes of this example,
we won't worry about modifying or deleting an existing user.
// Address book system module
module address_book_system
{
// Specify interface to our address book
interface address_book
{
// Unknown user exception
exception unknown_user {};
// User already exists exception
exception user_exists {};
// Lookup name from email address
string name_from_email(in string email)
raises (unknown_user);
// Lookup email from full name
string email_from_name(in string name)
raises (unknown_user);
// Record a new name and email
void record_user(in string name, in string email)
raises user_exists;
};
};
We start by declaring a module for our address book system (modules
can be mapped to Java packages). Inside the module, we declare our
interfaces and the exceptions they can raise. Since its such as
simple system, the methods of the interface will only return a string,
but we can create more complex return values if needed. As well as
returning values, we accept as input two strings for our record_user
method. As you can see, IDL really isn't to hard to pick up.
Once you've written your interface using IDL, you can then begin to
write client and servers in the language of the choice. We'll choose
Java for now, but there's no reason why the client or the server
couldn't be written in another language. Provided you have an
interface in IDL format, you could write code that interacts with the
object it describes.
From IDL to Java
Converting an IDL schema into Java source code is quite straightforward.
Sun provides a free tool, idltojava, that creates the source code for
you. This tool is currently distributed separately to JDK 1.2, but is
freely available for members of the Java Developer Connection.
idltojava -fno-cpp AddressBook.idl
Based on the name of your IDL schema's module, a package will be
generated that contains skeleton source code for your CORBA client
and server, as well a second package to cover our two exceptions. The
following is a list of the files it creates for us
\address_book_system\
_address_bookStub.java
address_book.java
address_bookHolder.java
address_bookHelper.java
address_bookPackage
_address_bookImplBase.java
address_bookPackage\
unknown_user.java
unknown_userHelper.java
unknown_userHolder.java
user_exists.java
user_existsHelper.java
user_existsHolder.java
As you can see, there are a lot of files! Fortunately, we only need to
work on three to implement a complete CORBA client and server. The
first file is a servant, which serves the requests made by clients.
The second is a server, which will accept requests, and the third is a
standalone application which will issue requests.
The full article, and source code, is available at
http://www.davidreilly.com/jcb/articles/javaidl/javaidl.html
- - - - - - - - - - - - - - - - - - - - - - - -
Introduction to RMI
By David Reilly
Remote method invocation allows applications to call object
methods located remotely, sharing resources and processing load
across systems. Unlike other systems for remote execution which
require that only simple data types or defined structures be passed
to and from methods, RMI allows any Java object type to be used -
even if the client or server has never encountered it before. RMI
allows both client and server to dynamically load new object types
as required. In this article, you'll learn more about RMI.
Overview
Remote Method Invocation (RMI) facilitates object function calls
between Java Virtual Machines (JVMs). JVMs can be located on separate
computers - yet one JVM can invoke methods belonging to an object
stored in another JVM. Methods can even pass objects that a foreign
virtual machine has never encountered before, allowing dynamic loading
of new classes as required. This is a powerful feature!
Consider the follow scenario :
Developer A writes a service that performs some useful function. He
regularly updates this service, adding new features and improving
existing ones.
Developer B wishes to use the service provided by Developer A. However,
it's inconvenient for A to supply B with an update every time.
Java RMI provides a very easy solution! Since RMI can dynamically load
new classes, Developer B can let RMI handle updates automatically for
him. Developer A places the new classes in a web directory, where RMI
can fetch the new updates as they are required.
Writing RMI services
Writing your own RMI services can be a little difficult at first, so
we'll start off with an example which isn't too ambitious. We'll
create a service that can calculate the square of a number, and the
power of two numbers (238 for example). Due to the large size of the
numbers, we'll use the java.math.BigInteger class for returning values
rather than an integer or a long.
Writing an interface
The first thing we need to do is to agree upon an interface, An
interface is a description of the methods we will allow remote
clients to invoke. Let's consider exactly what we'll need.
* A method that accepts as a parameter an integer, squares it, and
returns a BigInteger
public BigInteger square ( int number_to_square );
* A method that accepts as a parameter two integers, calculates their
power, and returns a BigInteger
public BigInteger power ( int num1, int num2 );
Once we've decided on the methods that will compose our service, we
have to create a Java interface. An interface is a method which
contains abstract methods; these methods must be implemented by
another class. Here's the source code for our service that calculates
powers.
import java.math.BigInteger;
import java.rmi.*;
//
// PowerService Interface
//
// Interface for a RMI service that calculates powers
//
public interface PowerService extends java.rmi.Remote
{
// Calculate the square of a number
public BigInteger square ( int number )
throws RemoteException;
// Calculate the power of a number
public BigInteger power ( int num1, int num2)
throws RemoteException;
}
Our interface extends java.rmi.Remote, which indicates that this is a
remote service. We provide method definitions for our two methods
(square and power), and the interface is complete. The next step is
to implement the interface, and provide methods for the square and
power functions.
Implementing the interface
Implementing the interface is a little more tricky - we actually have
to write the square and power methods! Don't worry if you're not sure
how to calculate squares and powers, this isn't a math lesson. The real
code we need to be concerned about is the constructor and main method.
We have to declare a default constructor, even when we don't have any
initialization code for our service. This is because our default
constructor can throw a java.rmi.RemoteException, from its parent
constructor in UnicastRemoteObject. Sound confusing? Don't worry,
because our constructor is extremely simple.
public PowerServiceServer () throws RemoteException
{
super();
}
Our implementation of the service also needs to have a main method. The
main method will be responsible for creating an instance of our
PowerServiceServer, and registering (or binding) the service with the
RMI Registry. Our main method will also assign a security manager to
the JVM, to prevent any nasty surprises from remotely loaded classes.
In this case, a security manager isn't really needed, but in more
complex systems where untrusted clients will be using the service, it
is critical.
public static void main ( String args[] ) throws Exception
{
// Assign a security manager, in the event that dynamic
// classes are loaded
if (System.getSecurityManager() == null)
System.setSecurityManager ( new RMISecurityManager() );
// Create an instance of our power service server ...
PowerServiceServer svr = new PowerServiceServer();
// ... and bind it with the RMI Registry
Naming.bind ("PowerService", svr);
System.out.println ("Service bound....");
}
Once the square and power methods are added, our server is complete.
Writing a RMI client
What good is a service, if you don't write a client that uses it?
Writing clients is the easy part - all a client has to do is call
the registry to obtain a reference to the remote object, and call
its methods. All the underlying network communication is hidden from
view, which makes RMI clients simple.
Our client must first assign a security manager, and then obtain a
reference to the service. Note that the client receives an instance
of the interface we defined earlier, and not the actual implementation.
Some behind-the-scenes work is going on, but this is completely
transparent to the client.
// Assign security manager
if (System.getSecurityManager() == null)
{
System.setSecurityManager (new RMISecurityManager());
}
// Call registry for PowerService
PowerService service = (PowerService) Naming.lookup
("rmi://" + args[0] + "/PowerService");
To identify a service, we specify an RMI URL. The URL contains the
hostname on which the service is located, and the logical name of the
service. This returns a PowerService instance, which can then be used
just like a local object reference. We can call the methods just as if
we'd created an instance of the remote PowerServiceServer ourselves.
// Call remote method
System.out.println ("Answer : " + service.square(value));
// Call remote method
System.out.println ("Answer : " + service.power(value,power));
Writing RMI clients is the easiest part of building distributed
services. In fact, there's more code for the user interface menu in
the client than there is for the RMI components! To keep things simple,
there's no data validation, so be careful when entering numbers.
The full article, and source code, is available at
http://www.davidreilly.com/jcb/articles/javarmi/javarmi.html
- - - - - - - - - - - - - - - - - - - - - - - -
The Java Coffee Break Newsletter is only sent out to email subscribers
who have requested it, and to readers of the comp.lang.java.programmer
and comp.lang.java.help newsgroups. If you are an email subscriber and
no longer wish to receive the JCB Newsletter, please unsubscribe using
the WWW form located at
http://www.davidreilly.com/jcb/newsletter/unsubscribe.html