|
|
YOUR FEEDBACK
|
TOP MICROSOFT .NET LINKS .NET Compact Framework
Connecting Microsoft Mobile Devices to Java Infrastructures
Integrating a .NET Compact Framework application with a Java back end
By: Christian Donner
Digg This!
If the task at hand is to connect a Pocket PC running the .NET Compact Framework to a Java back end, and if Web services are ruled out as an interoperability solution, there are not many viable options available. The one presented in this article may well be the only one. This solution requires MiddSol's MinCor.NET. The product is an object request broker for the Compact Framework written in C#. It supports Windows Mobile, Windows XP Embedded, and Windows CE .NET. Requirements
Because Remote Method Invocation (RMI; Java's own standard for distributed object interoperability) is based on the CORBA/IIOP protocol, it is possible to connect to an RMI server from any CORBA client, including a mobile .NET application. On the Java side, this can be accomplished with regular Java classes that implement the java.rmi.Remote interface or by writing Enterprise Beans (EJBs; see Figure 1). Today's application servers even expose Java Naming and Directory Interfaces (JNDIs) through a CORBA naming service provider, which can be used by the .NET client to locate the host. Because one of the assumptions was that the server code already exists, it will (for the most part) be considered a black box. The Java chat interface must be exposed through RMI, of course (see Listing 1; the listings and source code are online at www.sys-con.com/dotnet/source.cfm). The IDL file is the glue between the host and the subscriber code. It contains a generic description of the calling interfaces with abstract data types that can be mapped to the actual data types of the target platform. In the chat example, the subscriber and the host will act both as a server and a client. Please note that the term "subscriber" better describes the part of the application that runs on the mobile device than "client." This is because of the potential confusion with the client at the communication layer, which can be either side. The subscriber will initialize the session by sending a registration packet to the host, which the host will acknowledge by returning a list of subscribers. Once registered, the subscriber then sends messages to the host as needed. The host calls other subscribers to distribute the message to all participating devices. When a subscriber wishes to deregister, he must call the host again. MinCor.NET comes with a utility called MCjava2cs. exe. This little program will do most of the glue work for you. It opens existing JAR files and lists all the RMI and EJB interfaces found for selection (see Figure 2). In Figure 2, the tool is pointed to the ChatHost.jar of the example. The Host and Subscriber interfaces were selected. MCjava2cs further lists serializable Classes (passed by value) or selection (see Figure 3). The example contains two classes of this type that were both selected. The last step is to run the generation process that creates C# code for the selected interfaces (see Figure 4). The tool actually performs two distinct tasks. First, it extracts the IDL definition from the Java code. Second, it generates C# code based on the IDL generated during Step 1. The IDL file is transient because it is not needed once the C# code has been generated. The tool created a file named host.cs based on the name space of the Java interface. It contains the host class skeleton code and some helper methods. If this sounds like something you don't want to know, you can relax. MCjava2cs.exe allows you to write CORBA code without any knowledge of IDL syntax and IDL types. When I used the tool, I experienced problems with JVM version 1.4.2_04-b04, but it worked with JVM 1.4.2_05-b04. Also, make sure that there are no spaces in the path to the JAR file and the C# output path. These issues will likely be fixed by the time you download the trial software. To better understand the purpose of the methods that the Java host makes available, it is beneficial to take a detailed look at the communication between the host and a subscriber. In Figure 5, the host interface exposes three methods that will be called by subscribers: signOn(), signOff(), and sendMessage(). The method signOn()accepts one parameter (subscriberAccount) and returns a HashTable with all subscriber names. sendMessage() is called by the subscriber to send a message and requires the sender's name and the message as parameters. signOff() is called by the subscriber to end the chat session. Because the subscriber name is used as a key, it must be unique. The subscriber, on the other hand, must allow the host to update the display by exposing its interface to the host for a method call. displayMessage() requires two parameters: the name of the sender and the message itself. The class subscriberAccount is known to both the host and the subscriber and is passed by value. It holds information about a subscriber's name, hobby, and Subscriber interface. The latter must be exposed to the host so that the host can call the subscriber's displayMessage() method. See Listing 2 for how the Java implementation looks. The Client Project The code for the client user interface is of limited interest in the context of this article, with one exception. In the .NET Compact Framework, only the main thread of an application is supposed to access UI controls directly. Because of this restriction, the host cannot simply invoke the method displayMessage() to write to the subscriber's display (the ORB is multithreaded and displayMessage() runs as a separate thread). The main dialog's interface AsyncUIAccess provides a workaround. The implementation of the method writeLog() writes to a queue. A timer empties the queue on a regular basis and writes all content to the display. This interface is defined in MainDialog. cs. FrmChatSubscriber implements the writelog() method:
public interface AsyncUIAccess
{
void writeLog(
string a_strMsg);
}
The rest of the presentation code should be straightforward to read and understand and will not be discussed. Instead, the article will walk you through the Subscriber interface and the Connection class that provides a wrapper for the remote objects and manages the connection. The folder /Serializables in the Visual Studio project helps to organize the solution (see Figure 6). It contains the implementations of all serializable CORBA classes, or CORBA valuetypes. In this case, they are SubscriberAccountImpl and SubscriberInfoImpl. They are derived from Chat.SubscriberAccount (SubscriberInfo, respectively), which are generated classes in Chat.cs. These classes are used to pass subscriber information between the client and the server. SubscriberInfo does not expose the subscriber's interface, which is only needed by the host, and can therefore be safely passed to other clients in a hashtable. The suffix Impl is a naming convention that serves as a reminder of this fact. The generated parent class already defines the properties and has abstract getter- and setter-method declarations. Therefore, the implementation is rather simple (see Listing 3). The implementation of the subscriber interface exposes one method, displayMessage(), that the host can call (see Listing 4). AsyncUIAccess is the implementation of the display queue for the timer that was mentioned earlier. SubscriberPOA, the parent of the SubscriberImpl, is also a generated class. POA stands for Portable Object Adapter. When a client invokes a server object, the POA helps the request broker to activate the appropriate object and to deliver requests to it. The last module on the client side that deserves attention is Connection.cs. This class contains the methods that manage the communication between subscriber and host. It maintains a reference to the host and to its own interface. It also instantiates an object request broker instance (ORB; see Listing 5). initCORBA() contains standard CORBA initialization code. It uses the .NET DNS API to get the local device's IP address, instantiates a new ORB, retrieves a reference to the newly created root portable object adapter (POA), and "narrows" it to the correct type (Middsol.PortableServer.POA). Finally, it activates the POA that has been in a holding state. connectToHost() uses the Java Naming Services to locate the host. It requires an IP address, connects to the name server on this host, and requests the location of a server called ChatHost. AsyncUIAccess, although not needed by some of the methods, is passed to enable future improvements.displayListOfSubscribers() iterates through the list of subscribers that the host returned and writes each entry to the list box on the screen. Deploy and Test The client executable runs as a Windows application, too, which makes it very easy to test (see Figure 8). With these restrictions in mind, use the following steps to build and test the applications:
Conclusion Resources MICROSOFT .NET LATEST STORIES
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
|
SYS-CON FEATURED WHITEPAPERS MOST READ THIS WEEK BREAKING NEWS FROM THE WIRES
|
||||||||||||||||||||||||||||||||||