Component Object Model

March 11, 2007

Traditional operating systems only dealt with application binaries and not components. Hence, the benefits of good component-oriented design have till now never gone beyond the compilation step. In an object-centric world is’nt it still a puzzle why operating systems can’t recoganize objects? For a long time now, operating systems have been dealing only with application binaries (EXEs). Objects in one process could not communicate with objects in another process using their own defined methods. The operating system defined certain mechanisms of inter-process communication like DDE, TCP/IP, Sockets, memory-mapped I/O or named pipes etc. These objects needed to use these OS defined mechanisms to communicate with each other.

Components developed using Microsoft’s COM provide a way by which two objects in different object spaces or networks, could talk together by calling each other’s methods. This excellent technology forces the operating system to see applications as objects.

COM forces the OS to act as a central registry for objects. The OS takes the responsibility of creating objects when they are required, deleteing them when they are not, and handling communications between them, be it in the same or different processes or machines. One major advantage of this mechanism is versioning. If the COM object ever changes to a new version, the applications that use that object need not be recompiled.

The wonderful thing about COM components is that they are never linked to any application. The only thing that an application may know about a COM object is what functions it may or may not support. In fact, the object model is so flexible that applications can query the COM object at run-time as to what functionality it provides.

Garbage Collection is one other major advantage to using COM. When there are no outstanding references (a.k.a. pointers) to an object, the COM object destroys itself.

COM supports Marshalling. Distributed Computing purists will attest to the fact that marshalling is the process of packaging and transmitting data between different address spaces, automatically resolving pointer problems, preserving the data’s original form and integrity. Even though COM objects reside in separate processes or address spaces or even different machines, the operating system takes care of marshalling the call and calling objects running in a different application (or address space) on a different machine.

Over and above all this, COM is a binary standard. A fully compliant COM object can be written in any language that can produce binary compatible code. So you can write them using C, C++, Java, J++ or Visual Basic. All of the Windows NT shell has been written using COM.

What is COM?

COM stands for Component Object Model, and is a binary standard for getting pieces of code (components) to interact with each other, it’s layered on top of DCE RPC. Since COM is a binary standard, it’s language-independent, and we can write COM objects and clients in C, C++, Java, Visual Basic, and anything else that supports COM. Essentially it’s a form of object-oriented programming, since one creates objects, then invokes methods on them. It’s built it into Windows (which is where most people do COM programming), but will soon be available on other platforms (Software AG has already released a port of DCOM to Solaris and Linux, with (many) more on the way).

COM = OLE = ActiveX. (more or less)

COM (Component Object Model), OLE ( formerly Object Linking and Embedding, now it’s no longer an acronym), and ActiveX are the same thing. The only substantial difference that I’m aware of is that ActiveX objects are intended to be transfered across the networks (ie, the Internet), and so are optimized to be small in size.OLE is what grew out of inter-application data transfer (ie, how to get an Excel spreadsheet into a Word document), and tends to deal with those issues. COM is the architecture that underlies both ActiveX and OLE.

COM transparantly handles method invocation

Note that one uses COM to handle the details of getting method calls from clients to servers. Because COM handles these details, it’s possible for the method calls (messages) to be in the same address space (in process, or “in-proc”), different address spaces on the same computer (“local”), or different address spaces on different computers (“remote”)(this last case is handled by Distributed COM, or DCOM). The nice thing is that COM does this (pretty) transparantly, so that we could create an object with intention of running it as a local object, but move it to a remote computer later without having to change the code. This might not be optimal, but it’ll work.

Reference Counting

Since COM was originally intended to be used in C++, we don’t have garbage collection (yet — COM+ is a new runtime component that may offer garbage collection), but we still need a way to keep track of when objects should be deallocated. Ideally, we’d like the objects to delete themselves, because multiple clients can use the same object, simultaneously, without knowing that the others are using it. If one client were to delete the object while the other clients were still trying to use the object, there would be massive problems. We solve this problem with reference counting — the object itself keeps a count of the number of clients using it (who are refering to it, thus the name), and when that count is decremented to 0, it deletes itself. Each time a client starts using an object, it increments a private, internal reference count within the object (by calling the public AddRef method on that object). When the client is finished using on object, it decrements the private, internal count on the object ( by calling the public Release method on that object). When the reference count is decremented to 0, the object calls delete on itself, and is removed from memory. It’s a pretty snazzy way to solve the problem of trying to figure out when to delete the object, but can be tough to debug. Also, once the object has executed the delete this statement, the object should be careful to not access any member variables.

Calling Convention

Once you look at the code, you’ll note that all the methods have the __stdcall declaration. The __stdcall declaration specifies how arguments are pushed onto the stack when a method is invoked. Since you want your COM object to interoperate with other COM objects, you want to make sure that both your object and other COM objects use the same calling convention. Declaring them to use the __stdcall calling convention insures that your components call functions in the way that other components expect you call them. If you’re components won’t interact with anything else, then this doesn’t matter (this is why everything will work fine if you compile a component and a client, and forget to specify __stdcall with both of them).

Interfaces

We’ll ask COM to create a certain object for us, and then manipulate the object by invoking the object’s methods. Related methods are grouped together to form an “interface’, which serves to allow clients access to the object’s functionality without exposing implementation details. Clients are able to ask an object whch interfaces it offers for use by calling the QueryInterface method that every object has. Once an interface is released to the public, it should NEVER be changed, becuase it’s impossible to predict who is depending on the interface to be the way it is. And if the interface changes, some existing code somewhere could be broken. If you wanted a previously released interface to behave differently in the next version of your program you’d have to create a new interface, though the new interface could simply be an extension of the old one, with new methods tacked on to do whatever it is you left out of the first version.
Interfaces are not objects! It’s very easy to get these two concepts confused, especially when you’re first starting at this stuff. Remember to keep the concept of interface ( which is essentially a specification of how one object interacts with another) separate from the concept of object (the code that actually implements the interfaces)

IUnknown

Next, we’re going to briefly look at some specific interfaces that every object will have to worry about:: IUnknown and IClassFactory. First, IUnknown. Every object must support IUnknown, as it provides the interface for reference counting (AddRef and Release methods), as well as a mechanism for asking an object if it supports an arbitrary interface. The interface looks like the following:

HRESULT QueryInterface( REFIID iid, //Identifier of the requested interface
void ** ppvObject //Indirect pointer to the object );

ULONG AddRef(void);

ULONG Release(void);

IClassFactory

Once you’ve written the code for your object, you’ll need something to control the creation of it. While this might sound redundant, it’s actually very useful. If you want to create a single object that will service all requests, you can have the class factory create only a single instance of the object. If you want to do load-balancing among objects, the class factory may be the place to pick which object to use. Also, since COM is language independent, this allows one to create an object without knowing anything about the specifics of how a particular language wants to allocate objects (for example, when one creates COM objects in C, the class factory has to fill in the vtable manually, fake a constructor by initializing variables, etc). Note that class factories are in 1-to-1 correspondence with COMponents: one (and only one) class factory creates a certain type of COM object. The actual IClassFactory interface looks like:

IClassFactory: IUnknown
{
HRESULT QueryInterface( REFIID iid, void ** ppvObject );
ULONG AddRef(void);
ULONG Release(void);
HRESULT CreateInstance( IUnknown * pUnkOuter, REFIID riid, void ** ppvObject );
HRESULT LockServer( BOOL fLock );
};

The first three methods are IUnknown, while the last two are what actually do work. CreateInstance asks the classfactory to create a new instance of the object that the class factory is responsible for creating. pUnkOuter is used when aggregating objects (the COM equivalent of inheritance, which will be covered elsewhere). For simple stuff, this should be set to NULL. riid is a reference to an IID (a reference variable in C++, a pointer in C), which is the Interface that is requested on the created object. ppvObject is a pointer to a pointer that we’ll fill in with the interface if the call to CreateInstance is successful, and that we’ll zero out if it fails. Thus, we could create an instance of CMike, and ask to have the class factory return the interface for IFoo on the object with the following line:

CreateInstance( NULL, IFoo, ppvObj );

Class factories are unusual in that they can be unloaded from memory even when it’s reference count is nonzero. I don’t know why, but that’s how it is. If we want to make sure that the server isn’t unloaded until we want (eg, if we know that we’ll be creating a number of objects), we call the LockServer method. Calling LockServer( TRUE ) indicates that the object shouldn’t be unloaded until a corresponding LockServer(FALSE) is called. Since these calls can be nested, this generally means that a reference count is kept, with LockServer(TRUE) incrementing the count and LockServer(FALSE) decrementing it.


Apple Next Operating System – Leopard Sneak Preview.

March 11, 2007

Use it, never lose it

Time Machine browser in iMac

New in Leopard, Time Machine takes you beyond the backup. An automated system that regularly backs up everything on your Mac — music, photos, movies, documents — Time Machine also takes you back in time to restore your system. Enter Time Machine’s browser and look for files you may have deleted or lost, flip through multiple versions of the same project, or get a snapshot of your entire system from day one.

Get the message

More Mail

Set your email to stun with Mail 3 in Leopard. Create amazing invitations, letters, travelogues, and more — complete with photos and graphics — using new Stationery templates. Just choose your template, then use the built-in Media Browser to drag in your photos and more. And when those RSVPs start filling your inbox, you’ll stay organized with new Notes and To-Dos you can access from any Mac or PC. Plus, security enhancements including anti-phishing protection in Mail and Safari make Leopard the safest Mac OS for all your communications.

Show and tell

iChat gets a double dose of fun and functionality in Leopard. Chat from virtually everywhere with video backdrops. Create a video alter-ego in iChat using fun effects from Photo Booth, built into Leopard. Set up an iChat Theatre session to put on a virtual slideshow or Keynote presentation. Or Initiate Screen Sharing and take control of a friend or colleague’s display.

Enjoy the view

SpacesLeopard improves the way you manage and access information on your Mac. For starters, with Spaces, you can organize your windows into different groups — work, play, communication, creation — and move between them all with ease. Spaces gives you a one-click bird’s eye view of every project.

Plus, Dashboard adds new widgets that make life on the Web a one-click affair. Want to build your own Dashboard widgets? Dashcode gets your widgets running in minutes — even if you’ve never written a line of code.

Shine a light

Spotlight for Leopard introduces searching across network-mounted folders, so you can find what you need on more than one Mac. And with more powerful, flexible search options, Spotlight gives you more ways to find everything on your desktop — and beyond.

Get ready, get set, get Leopard

All these features and more are delivered to you in one universal, fully accessible, 64-bit operating system. Coming spring 2007.


First XULRunner Application

March 11, 2007

This article explores the Mozilla platform by building a basic
desktop application using XULRunner. Given that Firefox, Thunderbird
and the rest of the Mozilla suite is written using the platform, it a
safe bet that it can be used to build a basic application.

I want to build a simple XUL-based desktop application. If
you’re going to build a XUL-based desktop application, you’ll probably
need to install XULRunner. Let’s start by installing XULRunner
installed and making sure it runs a bare-bones application.

Step 1: Download XULRunner

You can find a download link on the main XULRunner page here on MDC.

The XULRunner download for Windows is a zip file, not a true
install. As a developer, I like the idea that XULRunner only needs to
be unzipped onto my machine. I am assuming that it doesn’t need to hook
into my Windows system and that’s a good thing.

The Mac version of XULRunner is distributed as a standard Mac OS X installer.

Step 2: Install XULRunner

On Windows, unzip the archive someplace reasonable. I unzipped it to a new C:\program files\xulrunner folder. Pretty simple so far. On the Mac, just run the installer, which installs XULRunner as XUL.Framework in the /Library/Frameworks directory.

Time to start a simple, bare bones application shell. Call it a XUL “Hello World” if you want.
It is definitely worth reading. Using the tutorial, I created a simple
bootstrap application.

Step 3: Create the application folder struture

On Windows, I created the root in a new c:\program files\xulapp folder, but you can create it wherever you like. Here is the subfolder structure:

/xulapp

   /chrome

     /content

       main.xul

     chrome.manifest

   /defaults

     /preferences

       prefs.js

   application.ini

Notice that there are 4 files in the folder structure: application.ini, chrome.manifest, prefs.js, and main.xul.

Step 4: Set up application.ini

The application.ini
file acts as the XULRunner entry point for your application. It seems
to be used to configure how your application intends to use the
XULRunner platform as well as configure some information that XULRunner
uses to run your application. Here is mine:

[App]

 Vendor=Finkle

 Name=Test App

 Version=1.0

 BuildID=20060101

 Copyright=Copyright (c) 2006 Mark Finkle

 ID=xulapp@starkravingfinkle.org[Gecko]

 MinVersion=1.8

 MaxVersion=1.8

You can find more information about the application.ini file in the article XULRunner:Deploying XULRunner 1.8.

Step 5: Set up the chrome manifest

The chrome manifest
file is used by XULRunner to define specific URI’s which in turn are
used to locate application resources. This will become clearer when we
see how the “chrome://” URI is used. Applications can be distributed
compressed in a JAR file or uncompressed as folders and files. I am
using the uncompressed method for now. Here is my manifest:

 content myapp file:content/

Note: Make sure your application name is lowercase and larger than 3 characters

Step 6: Set up preferences

The prefs.js file tells XULRunner the name of the XUL file to use as the main window. Here is mine:

 pref("toolkit.defaultChromeURI", "chrome://myapp/content/main.xul");

XULRunner preferences include:

toolkit.defaultChromeURI
Specifies the default window to open when the application is launched.
toolkit.defaultChromeFeatures
Specifies the features passed to window.open() when the main application window is opened.
toolkit.singletonWindowType
Allows configuring the application to allow only one instance at a time.

This is described in further detail in XULRunner:Specifying Startup Chrome Window.

Step 7: Create some XUL

Finally, we need to create a simple XUL window, which is described in the file main.xul. Nothing fancy here, just the minimum we need to make a window. No menus or anything:

<?xml version="1.0"?>

 <?xml-stylesheet href="chrome://global/skin/" type="text/css"?><window id="main" title="My App" width="300" height="300"

 xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

   <caption label="Hello World"/>

 </window>

Step 8: Run the application

The moment of truth. We need to get XULRunner to launch the bare-bones application. From a Windows command prompt opened to the C:\program files\myapp folder, we should be able to execute this:

            xulrunner.exe application.ini

Of course, xulrunner.exe must be in the PATH. Because of where I unzipped XULRunner, I could also try this if xulrunner.exe is not in the PATH:

       ..xulrunnerxulrunner.exe application.ini

On the Mac, you can run the application by opening a Terminal window, navigating to the myapp directory, and typing:

 /Library/Frameworks/XUL.framework/xulrunner-bin application.ini

You should now see a window that looks something like this. This particular screenshot is from Windows 2000.

XULSampleMyapp.png


XULRunner Installation & Uninstallation

March 11, 2007

Installing XULRunner

Mozilla provides XULRunner for Windows, Mac OS X, and Linux, in English:

Windows

  • Unpack the ZIP file to a new directory using an archive tool (7zip) is recommended. The following directory is recommended: C:\Program Files\Mozilla XULRunner\1.8.0.4 .
  • To register XULRunner with the system, open a command prompt and run xulrunner.exe --register-global (to register for all users) or xulrunner.exe --register-user (to register for one user only).

Mac OS X

  • Open the .pkg file within the installer and follow the directions.

Linux

  • Unpack the tarball to a new directory using tar -xzf xulrunner-1.8.0.4.en-US.linux-i686.tar.gz. The following directory is recommended: /opt/xulrunner/1.8.0.4 .
  • Register XULRunner with the system by running xulrunner --register-global (to install for all users, must be run as root) or xulrunner --register-user (to install for one user only).

Uninstalling XULRunner

Windows/Linux

  • From a command prompt, run xulrunner --unregister-global or xulrunner --unregister-user to unregister XULRunner just as you registered it during installation.
  • Remove the XULRunner directory.

Mac OS X

If you have multiple versions of XULRunner installed on Mac OS X, it is not possible to uninstall only one version.

  • To remove all installed versions of XULRunner, remove the /Library/Frameworks/XUL.framework directory.

XULRunner System Requirement

March 11, 2007

Windows

Minimum System Requirements

  • 233 Mhz processor
  • 64 MB of RAM
  • 50 MB of free disk space
  • Microsoft Windows 98

Mozilla Recommends

  • 500 Mhz processor
  • 256 MB of RAM
  • 100 MB of free disk space
  • Microsoft Windows XP

Mac

Minimum System Requirements

  • PowerPC G3 processor
  • 128 MB of RAM
  • 75 MB of free disk space
  • Mac OS X 10.2.x

Mozilla Recommends

  • PowerPC G4 or Intel processor
  • 512 MB of RAM
  • 150 MB of free disk space

Linux

Minimum System Requirements

  • 233 Mhz processor
  • 64 MB of RAM
  • 50 MB of free disk space
  • Linux kernel 2.2.14 (with glibc 2.3.2, XFree86-3.3.6, gtk+2.0, fontconfig/xft and libstdc++5)

Mozilla Recommends

  • 500 Mhz processor
  • 256 MB of RAM
  • 100 MB of free disk space
  • a modern Linux distribution

Introduction to XULRunner

March 11, 2007

XULRunner is a product in development which will serve as a runtime environment for XUL applications. It replaced or renamed the Gecko Runtime Environment. All XUL-based applications like Mozilla Firefox, Mozilla Thunderbird, Democracy Player and Songbird

will be able to run on XULRunner. It will provide mechanisms for
installing, deploying, upgrading, and uninstalling these applications.

The first stable developer preview of XULRunner was released in February 2006.

XULRunner 1.9 will be the first production release of XULRunner, and will be used and shipped by Firefox 3
(Q4 2007). The full planned featureset of XULRunner including
application management and embedding APIs will be available in this
release.

What is XULRunner

XULRunner is a Mozilla runtime package that can be used to bootstrap
XUL+XPCOM applications that are as rich as Firefox or Thunderbird. It
is similar to other existing runtime applications such as J2SE Java
Runtime Environment (JRE). It provides an innovative technology that
developers can use to enrich and integrate their desktop applications.

This runtime package provides a way for installing, upgrading,
and uninstalling XULRunner applications. XULRunner will also provide
libxul, a solution which allows the embedding of Mozilla technologies
in other projects and products. These applications can be written in
any Mozilla supported technologies. Some of these technologies are the
following:

  • HTML
  • XHTML
  • SVG
  • XUL

XULRunner application is an alternative to avoid the use of Firefox.
The following are the trade offs of using a XULRunner application:

Pros

  • Runs on its own independent process
  • Does not require Firefox to run
  • Markup based UI (like XAML)
  • Allows applications to be cross platform

Cons

  • Auto-update code would need to be written
  • Installation files are larger to download when including XULRunner binaries (+13MB)

Note: The listed pros and cons are not all the trade offs of
using XULRunner. Instead these are the trade offs of using XULRunner
application as oppose to Firefox.

What XULRunner Provides

The goal of XULRunner is to provide a solution for deploying XUL applications (primarily
Firefox and Thunderbird), as well as providing an embedding mechanism.
The following features are either already implemented or planned:

Contents

  • 1 Gecko Features
  • 2 User Interface Features
  • 3 Embedding APIs
  • 4 The “Maybe” List
  • Gecko Features

    • XPCOM
    • Networking
    • Gecko rendering engine
    • DOM editing and transaction support (no UI)
    • Cryptography
    • XBL (XBL2 planned)
    • XUL
    • SVG
    • XSLT
    • XML Extras (XMLHttpRequest, DOMParser, etc.)
    • Web Services (SOAP)
    • Auto-update support (not yet complete)
    • Type ahead find toolbar
    • History implementation (the places implementation in the 1.9 cycle)
    • Accessibility support
    • IPC services for communication between gecko-based apps (not yet complete)
    • Storage/sqlite interfaces (not yet turned on by default)

    User Interface Features

    The following user interface is supplied by XULRunner, and may be overridden by embedders under certain circumstances:

    • APIs and user interface for installing, uninstalling, and upgrading XUL applications. See the wikimo:XUL:Installation Story.
    • Extension Manager
    • File picker (uses native OS filepicker as appropriate)
    • Find toolbar
    • Helper app dialog/UI
    • Security UI (maintenance of SSL keychains, etc)

    Embedding APIs

    The following embedding APIs are provided by XULRunner:

    • Cross-platform embedding (XRE_InitEmbedding)
    • JavaXPCOM embedding
    • gtkmozembed (Linux only)
    • ActiveX control (Windows only) (not yet complete)
    • NSView-based-widget (Mac OS X only) (not yet complete

    The “Maybe” List

    The following features have been discussed and may be included if developer time permits and code size is controlled:

    • LDAP support
    • Spellchecking support (with or without dictionaries provided) see bug 285977
    • Core support for profile roaming (with application-specific extensibility)
    • PyXPCOM embedding (not yet complete)

    XULRunner will not supply:

    • Bookmarks or History UI (must be managed by the application/embedder)
    • XForms (XForms will be available as an extension)