Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Professional Java.JDK.5.Edition (Wrox)

.pdf
Скачиваний:
31
Добавлен:
29.02.2016
Размер:
12.07 Mб
Скачать

Chapter 11

Now run idlj to produce client and server stubs (to produce both client and server stubs, the -fall option is used):

idlj -fall FileNotification.idl

The following files were then generated:

FileNotificationStub.java

FileNotification.java

FileNotificationHelper.java

FileNotificationHolder.java

FileNotificationOperations.java

FileNotificationPOA.java

Notice how the only additional file generated with the -fall option was FileNotificationPOA.java. This is an abstract class that gives you the means to provide an implementation of FileNotification. By extending it and providing the implementation of the methods defined in the interface, you will have a CORBA Portable Object Adapter (POA) that can be connected to a running ORB. By connecting the POA to the ORB, the ORB will be able to route incoming requests for FileNotification to the correct instance.

The Implementation

Our implementation of FileNotification will extend FileNotificationPOA. Here you will have to provide simple implementations for the methods found in the file FileNotificationOperations

.java, since FileNotificationPOA implements FileNotificationOperations. This chapter will then go through the code necessary to do the following:

1.Implement the FileNotificationOperations interface.

2.Connect to the local ORB.

3.Create a Portable Object Adapter for your implementation of FileNotification.

4.Connect the POA to the ORB’s root POA.

5.Register your instance of FileNotification with the local COS Naming Service.

6.Connect to the remote COS Naming Service.

7.Obtain an instance of RemoteFileSystemWatcher.

8.Register your instance of FileNotification with RemoteFileSystemWatcher to receive the filesystem notification events.

9.Wait for filesystem events.

The key CORBA classes used in the example code are summarized in the following table. They are the minimal set of classes necessary to use a local ORB and COS Naming service to publish an instance of a CORBA object for use by remote clients.

516

Communicating between Java Components and Components of Other Platforms

Class

Function

 

 

org.omg.CORBA.Object

Class used to represent any CORBA remote

 

object reference.

org.omg.CORBA.ORB

Class used to represent a CORBA ORB. This

 

class provides the core CORBA infrastructure

 

services, and brokers incoming and outgoing

 

CORBA object method invocations.

org.omg.CosNaming.NamingComponent

Class used for representing a CORBA Name.

 

Names refer to instances of a particular object

 

running on a COS Naming service. With a

 

name, a client can look up a particular object

 

and receive a reference to it, and then begin to

 

use the object.

org.omg.CosNaming.NamingContext

Class used to represent the actual COS Naming

 

service. This class is used to perform the actual

 

object lookups to receive references to remote

 

CORBA objects.

org.omg.PortableServer.POA

Represents a Portable Object Adapter. Since JDK

 

1.4, the POA feature of the CORBA specification

 

was added to the Java implementation. POAs

 

allow for CORBA objects to be easily deployed

 

on different implementations of CORBA ORBs.

 

They connect a CORBA object reference to the

 

ORB, allowing for incoming requests for that

 

reference to be processed.

 

 

Your first task is to implement FileNotificationOperations in your class that extends the abstract class FileNotificationPOA that was generated by the idlj tool. Your implementation will simply print out what file system notifications were received to standard output:

public class FileNotificationImpl extends FileNotificationPOA {

public FileNotificationImpl() {

}

// next three methods are the implementation of FileNotification.idl public void fileModified(String fileName) {

System.out.println(fileName + “: Modified”);

}

public void fileDeleted(String fileName) { System.out.println(fileName + “: Deleted”);

}

public void fileCreated(String fileName) { System.out.println(fileName + “: Created”);

}

...

517

Chapter 11

These methods implement the CORBA interface found in the FileNotification.idl file. Now that you have the interface implemented, you must create the main() method that starts up your server, registers an instance of your FileNotification implementation with a local ORB, retrieves an instance of RemoteFileWatcher, and registers your instance of FileNotification with this remote instance to receive file system events.

Our main method begins by setting the properties necessary for the local ORB to find the COS Naming service daemon running in a separate process on your local machine. This is the naming service you will be using to register your instance of FileNotification. The java.util.Properties object in the code below stores where your ORB is running with its initial port. These parameters allow your ORB to connect to the COS Naming service running on port 1049:

public static void main(String[] args) throws Exception {

Properties props = new Properties(); props.put(“org.omg.CORBA.ORBInitialHost”, “localhost”); props.put(“orb.omg.CORBA.ORBInitialPort”, “1049”);

ORB orb = ORB.init(args, props);

...

Once you have your ORB instance, you must get the root Portable Object Adapter (POA). Every ORB has a root POA. From this POA, all additional POAs are attached in a treelike structure with the root POA being the root of the tree:

POA rootPOA = POAHelper.narrow(orb.resolve_initial_references(“RootPOA”));

You must activate the root POA so that the ORB will accept incoming requests:

rootPOA.the_POAManager().activate();

Now that the root POA is active, you need to create the POA that contains your implementation of FileNotification. Once created, you connect your POA to the root POA so it can actively accept requests. To retrieve the actual CORBA reference of your implementation, you use the

FileNotificationHelper object. The FileNotificationHelper object was also generated by the idlj tool and the narrow() method was used to take an org.omg.CORBA.Object reference and cast it to a FileNotification object (with CORBA, a standard Java cast would not do the trick):

FileNotificationPOA nPOA = new FileNotificationImpl();

// attach File Notification POA to the root and register a reference org.omg.CORBA.Object ref = rootPOA.servant_to_reference(nPOA); FileNotification fileNotification = FileNotificationHelper.narrow(ref);

The next step is to bind your reference to the COS Naming service. You will name your reference FileNotification. You then bind your CORBA object reference ref to the naming service. Your FileNotification instance is now ready to receive incoming requests:

// bind the reference to the local cos naming server NamingContext ctx =

NamingContextHelper.narrow(orb.resolve_initial_references(“NameService”));

518

Communicating between Java Components and Components of Other Platforms

NameComponent comp = new NameComponent(“FileNotification”, “ “);

ctx.rebind(new NameComponent[] {comp}, ref);

Now you must look up the remote CORBA object reference of the type RemoteFileSystemWatcher. This object allows you to register your local instance of FileNotification with it to receive file system events. The first step is to find the remote COS Naming service and lookup the object. To do this you must inform JNDI that you want to use a COS Naming context. The Java system property java.naming

.factory.initial is set to reflect this. The java.naming.provider.url tells JNDI where to look for the remote COS Naming service (though in this example, the so-called remote COS Naming service is running on the local machine, and hence the hostname localhost). You then perform a normal JNDI lookup. However, since you are using IIOP for the underlying protocol with RMI, you cannot simply cast the object returned to the appropriate type. You must use the static javax.rmi

.PortableRemoteObject.narrow() instead:

Hashtable env = new Hashtable();

env.put(“java.naming.factory.initial”, “com.sun.jndi.cosnaming.CNCtxFactory”); env.put(“java.naming.provider.url”, “iiop://localhost:1500”);

//connect to the remote cos naming service and lookup the RemoteFileSystemWatcher InitialContext remoteCtx = new InitialContext(env);

java.lang.Object fswRef = remoteCtx.lookup(“FileSystemWatcher”);

//register our File Notification reference to receive events from the watcher RemoteFileSystemWatcher watcher = (RemoteFileSystemWatcher) PortableRemoteObject.narrow(fswRef, RemoteFileSystemWatcher.class);

Now that you have a reference to RemoteFileSystemWatcher, you can register your local reference of FileNotification and start receiving file system events: You tell the ORB to run() and your program blocks so you can receive file system events:

//remote call to register our local FileNotification instance on the remote server watcher.registerNotfication(fileNotification);

System.out.println(“File Notification registered on remote server.”); System.out.println(“Waiting for file notification events...”); System.out.println();

// let our server run and wait for events orb.run();

That is all there is to it. Your implementation is finished. You implemented a CORBA interface, FileNotification, in Java. You produced stubs for another CORBA interface, RemoteFileSystemWatcher, to proxy requests to a remote implementation. You then set up a local ORB with your implementation of FileNotification, looked up the remote instance of RemoteFileSystemWatcher, and then registered your reference of FileNotification with the remote CORBA object. The remote CORBA object now calls your local FileNotification reference whenever a file system event occurs.

519

Chapter 11

The following is the full code listing for FileNotificationImpl.java:

package book;

import java.util.Hashtable; import java.util.Properties;

import javax.naming.InitialContext; import javax.rmi.PortableRemoteObject;

import org.omg.CORBA.ORB;

import org.omg.CosNaming.NameComponent; import org.omg.CosNaming.NamingContext; import org.omg.CosNaming.NamingContextHelper; import org.omg.PortableServer.POA;

import org.omg.PortableServer.POAHelper;

import ConsoleCorbaServer.RemoteFileSystemWatcher;

public class FileNotificationImpl extends FileNotificationPOA {

public FileNotificationImpl() {

}

// next three methods are the implementation of FileNotification.idl public void fileModified(String fileName) {

System.out.println(fileName + “: Modified”);

}

public void fileDeleted(String fileName) { System.out.println(fileName + “: Deleted”);

}

public void fileCreated(String fileName) { System.out.println(fileName + “: Created”);

}

public static void main(String[] args) throws Exception {

Properties props = new Properties(); props.put(“org.omg.CORBA.ORBInitialHost”, “localhost”); props.put(“orb.omg.CORBA.ORBInitialPort”, “1049”);

//connect to the local cos naming server, get and activate

//the RootPOA

ORB orb = ORB.init(args, props); POA rootPOA =

POAHelper.narrow(orb.resolve_initial_references(“RootPOA”));

rootPOA.the_POAManager().activate(); FileNotificationPOA nPOA = new FileNotificationImpl();

// attach File Notification POA to the root and register a reference org.omg.CORBA.Object ref = rootPOA.servant_to_reference(nPOA);

520

Communicating between Java Components and Components of Other Platforms

FileNotification fileNotification = FileNotificationHelper.narrow(ref);

// bind the reference to the local cos naming server NamingContext ctx =

NamingContextHelper.narrow(orb.resolve_initial_references(“NameService”)); NameComponent comp = new NameComponent(“FileNotification”, “ “);

ctx.rebind(new NameComponent[] {comp}, ref);

System.out.println(“File Notification bound to local ORB”);

Hashtable env = new Hashtable(); env.put(“java.naming.factory.initial”,

“com.sun.jndi.cosnaming.CNCtxFactory”); env.put(“java.naming.provider.url”, “iiop://localhost:1500”);

//connect to the remote naming service and lookup the RemoteFileSystemWatcher InitialContext remoteCtx = new InitialContext(env);

java.lang.Object fswRef = remoteCtx.lookup(“FileSystemWatcher”);

//register our FileNotification reference to receive events from the watcher RemoteFileSystemWatcher watcher = (RemoteFileSystemWatcher)

PortableRemoteObject.narrow(fswRef, RemoteFileSystemWatcher.class); watcher.registerNotfication(fileNotification);

System.out.println(“File Notification registered on remote server.”); System.out.println(“Waiting for file notification events...”); System.out.println();

// let our server run and wait for events orb.run();

}

}

Running the Example

To run your example, you first need to start up the remote CORBA server. You do this by running

ConsoleCorbaServer.exe (a compiled .NET binary):

ConsoleCorbaServer

This ConsoleCorbaServer creates a C# instance of RemoteFileSystemWatcher, and registers it for use over IIOP via a COS Naming service. ConsoleCorbaServer.exe has the instance of RemoteFileSystemWatcher set up by default to monitor the directory d:\book. This can be changed by calling its setDirectory() method (which is exposed via CORBA), but for the purposes of running the example, the default is fine.

Next you must start up your local COS Naming service with which you will register your instance of FileNotification. The JDK provides a CORBA COS Naming service with its orbd tool. To start up the naming service, simply run orbd from the command line:

orbd

521

Chapter 11

With no parameters specified, orbd runs on port 1049 (where your code will be looking for it). After orbd is running, you can now start your client program:

java book.FileNotificationImpl

The output screen shot in Figure 11-13 shows your program receiving some file system events after I created, modified, and deleted a text file in the d:\book directory.

Figure 11-13

Web Ser vices

Sometimes it is difficult to pin down any sort of definition to the term Web services. Web services are drowned in hype. Some proclaim them as the enabling technology for the next generation World Wide Web, the Semantic Web. Others say they will revolutionize business-to-business communication. Still others insist that every new server-side application must support them — in fact, any legacy systems that do not support Web services should be retrofitted or rewritten. Web services are more than just the latest craze in distributed programming, but only an understanding of the technology itself will help you design your software system — don’t do Web services for the sake of doing Web services.

So what are Web services exactly? Web services, from a technical vantage point, are actually pretty simple. They enable remote procedure calls. The protocol they are generally run over is not revolutionary, it is HTTP. XML defines the actual data being transported. In fact, Web services do not even support sessions out of the box. They do not support distributed objects out of the box. They do not come close to either RMI or CORBA in terms of features or reliability. They are not scalable, robust, or good for mission-critical applications. So why the hype? Web services quite frankly are so simple to understand and implement, that they become a very powerful tool. Web services value interoperability above

522

Communicating between Java Components and Components of Other Platforms

anything else. Interoperability is a goal in CORBA, but with Web services, it is the number one priority. Web services are not fast. They simply make it easy to interoperate from a large range of platforms. Even Microsoft is fully on board, and officially supports Web services as the recommended method for communicating between their new .NET platform and the Java platform. You know it’s big when Microsoft commits itself to interoperability with any other platform, especially Java.

Web services allow the exchange of structured data over the simple HTTP protocol. Yes, they can be used over other protocols. Yes, they can be forced to simulate the more advanced features of RMI and CORBA. But they shouldn’t. Web services must stay simple to be effective. They make no sense otherwise. (Otherwise the wheel has just again been reinvented.) CORBA or RMI are stable and quality implementations for distributed objects and components. Web services are simply intended to facilitate the sending and receiving of structured data over HTTP. Your Web browser displays HTML pages. Since you can read, all the computer must do is display the Web page. It does not understand the content. All it knows is that a table goes here, an image goes there, and the title of the document is News. This is a fine model, and the World Wide Web has thrived. However, what if these Web pages were machine-readable? If the data served on HTTP servers was structured in formats that computer programs could be easily written to make use of the data, a whole new slew of applications could be written. This is why Web services are drowned in hype. It’s not because the technology is revolutionary, because it’s not; it’s beautifully simple, and some would say a regression from either RMI or CORBA. Web services are revolutionary because they will enable a whole generation of new computer applications that maximize the knowledge and information stored in the World Wide Web.

Evolution of the World Wide Web

Tim Berners-Lee, the visionary who created the foundation for what you now know as the World Wide Web, envisions a greater evolution of that Web for tomorrow. Slowly over time the Web has been transitioning. The first Web sites were simple and only served up static content. Later on, database-backed Web sites allowed for the dynamic query and creation of content served over HTTP. Today, you can manage bank accounts, pay credit card bills, purchase merchandise, and compete in online auctions. The major limitation of today’s Web, though, is the fact that almost all of the content currently in place, the vast wealth of information, is only good for human consumption. The best technology behind search engines still is limited by keywords, simple site usage statistics, and primitive categorization. Advances in artificial intelligence haven’t been all that advancing for a field where the same principles that applied 30 years ago still apply today and aren’t changed a whole lot by the more powerful machines of today.

Web services are one technology to bridge the gap from a human-readable Web to a machine-consum- able one. Imagine if the popular retailers, search engines, online auction sites, stock tickers, and news services all had simple APIs to programmatically access their content. Entirely new information-centric applications could be written that simply cannot exist now — portals like my.yahoo are the best we’ve got. I’ve created a hypothetical weather Web site. I say hypothetical because it doesn’t exist online, and it produces completely random weather forecasts. It does, however, give a good view of what the Web looks like today. Figure 11-14 shows a screen shot from this hypothetical site, random-weather.org.

523

Chapter 11

Figure 11-14

It is a simple site; users enter their zip code into the form and then receive their weather forecast — not all that different from real weather sites, except of course, that this one is hideous. This page is encoded in HTML, and works with the browser to send the Web server whatever zip code was typed in (as with any Web application). Here is the simple HTML of this page:

<html>

<head>

<title>Weather Page</title> </head>

<body>

<h1>Get the Current Weather!</h1>

<form method=”get” action=”weather.jsp”>

<table border=”0” cellspacing=”2” cellpadding=”2”> <tr>

<td><input name=”zipcode” type=”textbox”/></td> <td><input type=”submit” value=”Get Weather!”/></td>

</tr>

</table>

</form>

</form>

</body>

</html>

Note that there are only a couple of input tags, and this is where the information is exchanged. Figure 11-15 shows what the resulting Web page from this dynamic site looks like.

524

Communicating between Java Components and Components of Other Platforms

Figure 11-15

A nice, simple little page displays the random weather forecast. The HTML looks like this:

<html>

<head>

<title>Weather for Zip Code: 12345</title> </head>

<body>

<h1>Weather for Zip Code: 12345</h1>

<table border=”0” cellspacing=”2” cellpadding=”2”> <tr>

<td>High Temperature</td>

<td>93</td>

</tr>

<tr>

<td>Low Temperature</td> <td>73</td>

</tr>

<tr>

<td>Description</td> <td>Partly Cloudy</td>

</tr>

<tr>

<td>Barometer</td>

525

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]