| By Vikram Roopchand | Article Rating: |
|
| February 19, 2007 01:00 PM EST | Reads: |
13,069 |
1. Each Windows machine on the network has a subsystem known as the Service Control Manager (not to be confused with the Windows "Services" system). It's a DCE/RPC server that listens at port 135 and runs inside rpcss.exe. The SCM makes sure that when a client request is made, the appropriate COM server is connected and ready to receive the request. It provides an RPC interface, known as IRemoteActivation, which has only a single operation, "RemoteActivation," designed to activate a COM server on a remote machine. This, by the way, is an important difference between DCOM and classic RPC where the server must be running before the client can connect to it. The SCM resides at well-known endpoints, one for each supported network protocol (135 for TCP/UDP).
2. When the client gets a "CoCreateInstance" call with the execution context set as Remote (CLSCTX_REMOTE_SERVER specifies to the runtime that the COM server is located on a remote machine), the COM runtime consults the Windows registry for the "RemoteServerName" named-value. This value is located at [HKEY_CLASSES_ROOT\APPID\(CLSID of TestCOMServer)]. If a machine name is found under this key then the request to activate the COM server is forwarded to SCM on that remote machine. The remote SCM uses the IRemoteActivation interface to activate the object identified by CLSID_ITestCOMServer.
3. What does it mean to "activate" a COM object? We will get to that after I talk about the IOxidResolver. I think it's important to clear these basics up otherwise things could become quite confusing.
Each machine that supports the COM network protocol supports a one-per-machine service known as the "OXID Resolver." Like the SCM, it also contains an RPC interface "IOxidResolver." Oxid Resolver performs many important operations, primarily maintaining the binding information necessary to connect to the COM components being exported. It also takes care of keeping the exported objects alive by receiving pings from the COM clients (otherwise they'd be garbage collected) and does lazy protocol registration for servers scoped by the Oxid Resolver. I'll explain this last point a bit more. Each COM server can decide to support a certain set of protocols over which it can be contacted. For example, a server may want to answer only on UDP or TCP or HTTP or all three. Instead of reserving ports for each protocol even before it's activated, a server delays this to the time it's actually activated on a requested protocol. This is quite useful in preventing the machine from running out of ports.
4. Okay, coming back to activation. Activation should be seen as a set of activities that bring a COM server to a "ready to receive requests" state. In general, it means locating the COM server on the remote machine using the Windows registry, registering its connection information with the Oxid Resolver, marshaling the reference to its IUnknown (rather the "IRemUnknown") interface, and sending it back to the callee (explained in step 7).
5. On the remote machine, when the server is started by its SCM, two activities take place.
- The server is associated with an "object exporter" and assigned an object exporter identifier (OXID). An object exporter keeps track of all the interfaces (like in our case ITestCOMServer), which this COM server will export or import.
- The COM runtime also associates an "Oxid Object" with the COM server, which implements the COM interface "IRemUnknown." It forms the remote proxy for the base "IUnknown" interface. Please note the standard IUnknown interface is never remoted in COM. In its place, the IRemUnknown interface is remoted and results in local calls to QueryInterface, AddRef, and Release on the server.
6. I've talked about the SCM and the Oxid Resolver service. They are important infrastructure services. One provides for activation and the other for ```discovering the path and means to the activated object.
7. Up until now, in executing "CoCreateInstance" we've been able to activate a COM object. We still need to return the interface pointer, which will uniquely identify this activated COM object and allow us further operations on it (like a QueryInterface). Microsoft extended the Network Data Representation (the presentation layer protocol responsible for packaging semantics of the DCE/RPC datatypes) to add the concept of a "Marshaled Interface Pointer" (MIP from hereon). The MIP symbolically represents an interface reference to an object. It consists of two elements, an array of bytes and a marker specifying how to interpret this array of bytes. There are three variations to the interpretation, but I'll stick to the STANDARD type. The array of bytes representing the STANDARD interface pointer consists primarily of a 128-bit GUID known as IPID, short for interface identifier, that uniquely identifies an interface - it has a one-to-one mapping with each marshaled interface, i.e., ITestCOMServer will have a single IPID - an OXID and a 64-bit object ID (OID) that uniquely identifies the object on which the IPID is found. There's one-to-one mapping between an object instance (implementing one or more interfaces thus IPIDs) and the OID. This OID is quite useful during pinging. Along with all this the MIP also contains the full bindings for the OXID Resolver service running on the remote machine.
8. When the marshaled interface pointer is returned to the client side through the server-side and client-side SCMs, the COM runtime extracts the OXID, addresses the remote OXID Resolver from MIP, and calls the ResolveOxid() method on its local OXID Resolver to get the bindings ("how to connect" information) identified by the OXID (it has to reach the COM server now for further operations).
9. The clients-side OXID Resolver checks to se if it has a cached mapping for the OXID; if not, it invokes the ResolveOxid() method of the server-side OXID Resolver - it can since it has the address information from the MIP - which returns the registered RPC binding of the COM server.
10. The client-side Resolver caches the mappings, and returns the RPC bindings of the COM server to the COM runtime. This lets the runtime create an RPC channel that's connected to the Object exporter of the COM server.
11. The CoCreateInstance call is now complete.
Phew! I have drawn a picture to explain this entire cycle, just follow the alphabet.
I hope I was able to provide a concise introduction to the discovery and activation cycle. Let's see how the "QueryInterface" works and how the API call "Add (...)" is handled.
12. The remote connection has now been established and we have an interface pointer to the remote IUnknown (the "IRemUnknown"). A QueryInterface () call to obtain the "ITestCOMServer"" interface will result in the following activities taking place.
13. When the client invokes the IUnknown::QueryInterface, the COM runtime invokes the IRem-Unknown::RemQueryInterface method on the OXID object in the target object exporter. The OXID object then invokes the QueryInterface() method on (possibly multiple) interfaces in the exporter (remember, the exporter knows all the interfaces the COM server has exported out). Please note that the IRemUnknown::RemQueryInterface method differs from the IUnknown::QueryInterface method since it can request several interface pointers in one call. The standard IUnknown::QueryInterface method is actually used to carry out this request on the server side.
14. If found, the requested interface from the COM server is then marshaled as a MIP and sent back to the callee. This MIP carries a new IPID symbolizing this interface. The OXID and OID remain the same.
15. Now that we have the interface pointer let's call "Add" on it. Upon receiving the ptrTestServer->Add(1, 2, int*) call, the COM runtime marshals the parameters in the NDR format and channels the request to the target object exporter identified by the OXID-resolved RPC binding (we did that in steps 9 and 10).
16. The COM runtime on the server side finds the target interface based on the IPID that's contained in the RPC header. This IPID is of the ITestCOMServer interface that was returned to the client during a previous QueryInterface call.
17. With the help of the Object exporter, the COM runtime invokes the method Add(...) on the correct interface of the COM server object and marshals the return values in the NDR format. These values are sent back to the callee using RPC infrastructure.
18. The same cycle follows during the Release() call, the COM runtime invokes the IRemUnknown::RemRelease() method on the OXID object in the target object exporter. The OXID object then invokes the Release() method on (possibly multiple) interfaces in the exporter. (Figure 4)
This completes the entire cycle of obtaining an interface, executing an API on it, and subsequently releasing it. There's an additional task that the COM runtime also does and that's keeping the COM Server objects alive during a session. This is done via a ping mechanism. Pinging is carried out on a per-object (per-OID), not a per-interface (per-IPID) basis. Architecturally, at its server machine, each exported object (each exported OID) has associated with it a "ping period" that must elapse without getting a ping on that OID before all the remote references to IPIDs associated with that OID can be considered to have expired. Once expiration has occurred, the interfaces behind the IPIDs might get reclaimed (exactly when is implementation-specific).
I've tried to keep the explanation of DCOM internals as simple as possible. There's much more that happens, but I'm running out of space and I think you're running out of patience, so let's get to j-Interop.
j-Interop
Suffice it to say j-Interop implements
almost the entire DCOM protocol with its own Oxid Resolver service,
pinging mechanism, Object exporter, etc. These are required for
handling event callbacks, proxying a Java server in place of a COM
server (bi-directional access), and making sure that the COM server
isn't garbage collected while a client is connected to it and vice
versa.
The library comes with pre-implemented packages for automation. This includes support for IDispatch, ITypeInfo, and ITypeLib. For more flexibility, it provides an API set to invoke operations directly on a COM server without going through automation. Another important feature is to allow full access and manipulation of the Windows Registry in a platform-independent manner.
The implementation has been tested on all advanced Windows and Fedora platforms and displays upward compatibility from JRE 1.3.1. For more technical specifications please visit http://j-interop.sourceforge.net.
I'll show you an implementation using j-Interop to call the ITestCOMServer from Java is Listing 1.
As you can see it's pretty straightforward. The ITestCOMServer supports the IDispatch interface. I've shown both ways of accessing the COM server, i.e., via the dispatch interface as well as via a direct call. From my experience, I'd suggest using the IDispatch interface, whenever it's available. It's much easier to program that way.
Figure 5 is normally how a Windows COM client communicates with its COM server. j-Interop does this as well and so for the COM server it's like an ordinary COM client. Whether the Java application is on Windows or Unix, it doesn't matter.
More examples and documentation can be downloaded from the SourceForge site mentioned previously.
The advantages offered by using a non-native library like j-Interop include:
- Clean integration of two of the leading technologies without writing any native code: j-Interop eliminates any need to write native (JNI) DLLs, cutting development time, and shortening the entire software lifecycle for the products (based on j-Interop). Such products are also saved from any kind of instable functions that result from poorly written native code (DLLs).
- Accessing COM components from any type of Java client, including applets, EJBs, servlets, JSPs, and standalone applications: Since it's pure Java, j-Interop can be used within any J2EE server and on any platform (that supports Java).
- Maximizing reuse of existing Java and COM components: All the plumbing on interoperating with COM servers is done by j-Interop, it makes reusing same components again, instead of porting back and forth between domains, a more lucrative and viable option.
- There should no longer be a dependency on cross-platform resources thus minimizing cost and im-proving quality: The same resources for Java can be used without any additional training/competency building and the turnaround time can be brought down substantially. Not having to deal with native code also removes the complexity associated with maintaining the same. The code is now much cleaner and distinctly segregated between the two domains. Debugging the projects based on j-Interop is substantially easier than debugging JNI-based DLL projects.
- Easier deployment since there's no custom code at the server: No special treatment has to be given to j-Interop clients, they just behave like standard DCOM clients. This is a big advantage in terms of administering the machines where the COM servers are deployed. The administrator doesn't have to care about security or the instability of native components bringing the server down (Denial of Service).
DCE/RPC stands for Distributed Computing Environment/Remote Procedure Calls. It originated from Network Computing System (NCS) RPC developed by Apollo (which later got acquired by HP).DCE/RPC specifies a complete set of APIs and Models to abstract the usual nuances of an RPC system like a named lookup, subsequent handshake\binding, passing of call data between two parties , handling communication errors, security etc.. It provides protocol support for both Connectionless and Connection Oriented communication and has a wide transport base, UDP, TCP/IP, SMB, HTTP to name a few. It also has a generic security model supporting several authentication mechanisms such as DCE, Kerberos and GSSAPI.
The full specification can be obtained from www.theopengroup.com.
Published February 19, 2007 Reads 13,069
Copyright © 2007 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Vikram Roopchand
Vikram Roopchand is a Technical Architect working for Infosys Technologies Ltd. (www.infosys.com). He has about 8.5 years of experience and specializes in Cross Platform development across Content Management and Business Intelligence domains.
- 4th International Cloud Computing Conference & Expo Starts Today
- Publishing Synergy: Blog, Twitter and Ulitzer
- Performance Tuning Essentials for Java
- Cloud Expo New York Call for Papers Deadline December 15
- Google Wave
- IBM Hardware Chief, Intel VC Exec Arrested in Insider Trading Scam
- Cloud Computing Can Revitalize Your Career as Software Developer
- SOA World Magazine "Readers' Choice Awards" Voting Is Now Open
- Oracle+MySQL Opponents Take to the Barricades
- Virtualization Expo Call for Papers Deadline December 15
- Oracle Faces Growing Price for MySQL
- SpringSource Moving to Spring 3.0
- 4th International Cloud Computing Conference & Expo Starts Today
- Deputy CIO of the CIA to Keynote 1st Annual GovIT Expo
- Publishing Synergy: Blog, Twitter and Ulitzer
- Performance Tuning Essentials for Java
- Cloud Expo New York Call for Papers Deadline December 15
- Cloud Computing Expo: Exclusive Q&A with Yahoo! SVP Cloud Computing
- Google Wave
- IBM Hardware Chief, Intel VC Exec Arrested in Insider Trading Scam
- Cloud Computing Can Revitalize Your Career as Software Developer
- Oracle-Sun: IBM Reportedly Behind Delay
- Citrix Aims To Cripple VMware’s Cloud Designs
- Oracle Trashes HP Relationship for Sun
- After Ubuntu, Windows Looks Increasingly Bad, Increasingly Archaic, Increasingly Unfriendly
- SCO CEO Posts Open Letter to the Open Source Community
- Simula Labs Launches Hosted Delivery Platform To Enable Enterprise Open Source Adoption
- Where Are RIA Technologies Headed in 2008?
- Source Claims SCO Will Sue Google
- How Open Is "Open"? – Industry Luminaries Join the Debate
- Latest SCO News is Plain Weird
- IBM Tells SCO Court It Can't Find AIX-on-Power Code
- SCO Claims Linux Lifted ELF
- Flashback: Investing in 'Professional Open Source' - Exclusive 2004 Interview with David Skok, Matrix Partners
- HP Starts Pushing Desktop Linux
- Linux Business Week Exclusive: Linux Kernel To Be Re-Written To Counter Microsoft FUD





























