CSE775 - Distributed Objects

Lecture #7 - Managed Code Infrastructure

COM RunTime, CLR, & JVM

Web Resources:

Linux:
The Linux Documentation Project, GNU Project, GCC, GDB, Make, glibc, Linux Tutorial - administration and basic knowledge, Linux Tutorials, eclipse
Windows:
.Net CLR, SysInternals, Best SysInternals Tools, Dr. Dobb's Journal, Windows Forms
COM:
COM at MSDN, IDL Language, base MIDL types, OLE data types, IDL attributes, MIDL data types, MIDL Language Reference
Other:
Code Project, The Java Tutorials - Oracle, Java Package summary

Content:

Components, discussed briefly in the last lecture, and managed code, which we start discussing in this lecture, are two different attempts to provide a development environment that supports building large systems on multiple platforms.

  1. Syllabus describes topics to be covered, reading material for you to digest before coming to class, and due dates for the assigned projects.
  2. Component Goals:

    Build large systems that are distributed over several processes and often several machines, using languages that are best suited for the development objective and developer skill set.

    The ideal is to create component building blocks in any language and use them to compose large systems, so much of the effort is simply to provide code glue to bind together existing components. The term "Software ICs" has sometimes been used for this component model.

    One part of this model is the notion that highly skilled developers will create the components and other developers will compose them to build products, which presumably takes less experience.

  3. The Problems:

    Software built from different languages is not necessarily compatible. That is especially true when C and C++ are part of the language mix since they do not have binary standards, and true to a lesser extent for all languages.

    We can't expect to throw an exception in C++ code and have that caught in another component built with a different language, or even with C++ generated by a different vendor's compiler.

    We can't expect to share memory-mapped files with code written in different languages. They may use incompatible locking constructs to synchronize access to the shared information and may use incompatible formats for the data.

    We can't expect to make function calls between anything except code built with the same compiler, as the stack frame protocol is not standarized by all languages.

    Not all popular languages are supported on many platforms. For example, the .Net framework and its C# language were available only on Windows. There has been an interesting project, mono, that has been porting the .net framework and C# to other platforms. Unfortunately the company that supported mono for several years was bought by another. Whether mono will continue to receive adequate support to continue development is unclear.

    When clients call components in another process or on another machine, the lifetime of objects created by those calls become an issue. The component service has no way to know when the client no longer needs the object. If the service runs in an environment where there may be many clients over a long period of time, this becomes an important issue. We will discuss this further, below.

  4. The Successes:

    Sockets are a low-level communication mechanism that work with any language that abides by the Berkely Sockets de Facto standard. Sockets simply send and receive bytes, so virtually all languages suitable for building applications can communicate with other code written in other languages if they both use sockets and agree on message-framing and talk management protocols.

    Hyper Text Transport Protocol (HTTP) provides a text-oriented message-passing process, based on sockets, for communication that is the basis for today's web. The bodies of messages can hold binary information, but each message must have a text header, with lines holding key-value pair information that supports transporting information between platforms. One of the key-value pairs specifies the length of the message body, so the underlying sockets can extract binary or a binary chunk and use it appropriately.

    Web Services provide a communication standard based on Simple Object Acess Protocol (SOAP) that provides a Remote Procedure Call (RPC) environment for communication between most modern platforms. Web services, like HTTP, are based on sockets.

    COM supports composing components developed in C, C++, and Visual Basic, but only on the Windows platform. From its beginning, COM has supported interprocess communication, and in later versions it became DCOM and supports inter-machine communication. DCOM was the basis for all Windows Networking for several versions of the Windows operating system and is still the basis for remote processing using the interesting PowerShell scripting language.

    Interoperation: The .Net infrastructure - Library Framework and Common Language Infrastructure (CLI) - supports interoperation between code built with any of the .Net languages and C, C++, and COM. Really all the .Net languages are just syntatic wrappers around the same OO language implemented in Microsoft Intermediate Language (MSIL). Interoperability between native and managed code works very effectively on the Windows platform. That does not appear to be the case for other platforms. Java provides Java Native Interface (JNI) but the strong performance and safety guarantees that pure Java provide are lost when JNI is used.

    Interception: is the process of passing each call to an object through one or more filters that may affect the parameters of the call or prevent the call from executing, perhaps for security reasons. Interception can also filter any return responses of the called function. Interception is the basis for synchronized methods which silently take a lock on the way into a function and release the lock on the way back. This serializes access to the method without the developer doing any locking. The only requirement is to decorate the method with a [Synchronized] attribute. Interception is a useful by-product of the managed code model, not directly supporting its composable building block goal.

    GUI Frameworks: One of the irritations in developing native code is that building Graphical User Interfaces (GUIs) with native code frameworks has always been a very clumsy affair. The last major effort by the Microsoft folks to develop a native GUI framework, the Microsoft Foundation Class (MFC) framework is a large, rigid affair with an insistence on a particular architecture and many, many classes that developer's have to understand in significant detail in order to build anything other than a default application. Similar frameworks on the Linux platform, for example gtk+ and KDE, suffer from some of the same problems. They all are just ackward to use. Managed code has provided much simpler and more effective frameworks like Java's Swing, .Net's WinForms and especially the very powerful Windows Presentation Foundation (WPF) framework.

  5. Managed Environments

    Managed code has been implemented in two ways, as you will see below:
    • COM - a lightly managed environment:

      The Microsoft Component Object Model (COM) is supported by a set of Windows API facilities and services that manage instantiation and remoting. COM runtime and its objects are based entirely on native code.

      COM introduced a notion of isolation call the Apartment Model. An apartment is a COM-RunTime artifact that is created by a client of a COM object by making a function call into the COM API before asking the RunTime to create an instance of the object, which then joins the apartment. All calls between apartments are marshaled through proxies, which helps to isolate problems to a single apartment. The apartment model subsequently evolved into the .Net Application Domain.

      Apartments come in several flavors, but the most common is the Single Threaded Apartment (STA). It guarantees safe operation in an environment with many concurrent clients by serializing all service requests through a Windows message loop. Concurrent requests are deposited in a thread-safe message queue which are then retrieved, one at a time, by a single thread - the thread that created the STA. This is exactly the same process used to insure that Graphical User Interfaces (GUIs) can safely operate with inputs from many concurrent sources without providing locking of shared resources internally.

      Every GUI developed for the Windows platform uses an STA. That includes the original Win32 windows, Microsoft Foundation Classes (MFC), WinForms, and Windows Presentation Foundation (WPF). Even though WPF threw away the control component basis for all earlier GUI frameworks on windows, each WPF application still runs in a single Windows OS window that processes inputs in the STA way.

    • Java JVM:

      The Java Virtual Machine (JVM) is a stack-based execution environment developed for the Java Language but also used by other languages like Python and Ruby. The JVM originally interpreted Java bytecode, the product of the Java compiler, on a JVM running on the execution platform, e.g., Windows, Linux, OSX, Unix, ... All recent versions of the Java language runtime have included a Just-in-Time (JIT) compiler that compiles Java bytecode into native code and maps the stack locations onto machine registers.

      The Java Programming Environment (JPE) provides a large set of packages and Jar files to support management of machine resources like files, java.io, directories, javax.naming.directory, construction of GUIs, java.swing, threads, java.lang.thread, and data, java.sql and java.xml.

      Java is not the first language to be hosted in a virtual machine. Smalltalk, for example, used a VM long before Java was created. It is, however, the most widely used of the modern languages that use VMs to promote cross-platform development.

    • .Net CLR:

      The .Net Common Language Infrastructure (CLI) is a fully managed environment - a near clone of the Java Programming Environment. All .Net code is managed and runs in a stack-based virtual machine referred to as the Common Language Runtime (CLR). The CLR, in concert with the .Net Framework Library, supports managing memory allocation and deallocation, object lifetime, exceptions, use of shared memory, function calls to other .Net languages, and interoperation with native code and COM objects via wrappers - Runtime Callable Wrapper (RCW) and COM Callable Wrapper (CCW).

      The C++/CLI managed language, based on C++, can directly make and receive calls from native C++. This means that C++/CLI can serve as a light-weight bridge between the managed and native worlds. Any .Net language can make calls into a DLL built with C++/CLI which, in turn, makes calls to and from native C and C++. We will see examples of this in the next few lectures.

      The .Net CLI provides a successor to COM apartments in the Application Domain and Context. Every process that runs .Net managed code creates an instance of the CLR, a COM object, when the process starts. The CLR contains a default Application Domain and Context Object. A process can have multiple Application Domains which are created by code in the default Domain. Each of them can be created, stopped, and unloaded without affecting other Domains in the process. An exception in one domain does not affect the other Domains, even if unhandled. Code in one Domain cannot directly access code in another. Instead cross Domain calls must be marshaled using proxies, just as for COM apartments. The Context object serves to associate its properties with each object bound to it. These are often security properties, so many .Net objects may be operating in the same process with different security attributes. We will see, in later lectures, how to bind an object to a specific context.

      Like Java Packages, the .Net Framework Class Libraries (FCL) provide functionality for creating and managing threads and processes, remote communication using sockets or socket wrappers, exploring files and directories, and managing XML and Relational Data. In addition, the FCL provides a lot of support for interacting with the Windows API. Most of the functionality exposed by the Windows operating system is wrapped by classes in the FCL, making it much easier for developers to access that functionality compared with making calls directly into the native Windows API.

  6. Managed Code Examples:

    COM:

    We will discuss each of these in later lectures. You may find it amusing to peek ahead now.

    Java:
    • Hello World
    • Simple Swing GUI
    C++\CLI: .Net C#: